Resultify tools::delete_file()

This commit is contained in:
link2xt
2023-01-28 11:33:01 +00:00
parent ae564ef702
commit ba3e4c5dff
3 changed files with 55 additions and 58 deletions

View File

@@ -700,20 +700,16 @@ async fn export_self_keys(context: &Context, dir: &Path) -> Result<()> {
for (id, public_key, private_key, is_default) in keys { for (id, public_key, private_key, is_default) in keys {
let id = Some(id).filter(|_| is_default != 0); let id = Some(id).filter(|_| is_default != 0);
if let Ok(key) = public_key { if let Ok(key) = public_key {
if export_key_to_asc_file(context, dir, id, &key) if let Err(err) = export_key_to_asc_file(context, dir, id, &key).await {
.await error!(context, "Failed to export public key: {:#}.", err);
.is_err()
{
export_errors += 1; export_errors += 1;
} }
} else { } else {
export_errors += 1; export_errors += 1;
} }
if let Ok(key) = private_key { if let Ok(key) = private_key {
if export_key_to_asc_file(context, dir, id, &key) if let Err(err) = export_key_to_asc_file(context, dir, id, &key).await {
.await error!(context, "Failed to export private key: {:#}.", err);
.is_err()
{
export_errors += 1; export_errors += 1;
} }
} else { } else {
@@ -733,7 +729,7 @@ async fn export_key_to_asc_file<T>(
dir: &Path, dir: &Path,
id: Option<i64>, id: Option<i64>,
key: &T, key: &T,
) -> std::io::Result<()> ) -> Result<()>
where where
T: DcKey + Any, T: DcKey + Any,
{ {
@@ -755,16 +751,16 @@ where
key.key_id(), key.key_id(),
file_name.display() file_name.display()
); );
delete_file(context, &file_name).await;
// Delete the file if it already exists.
delete_file(context, &file_name).await.ok();
let content = key.to_asc(None).into_bytes(); let content = key.to_asc(None).into_bytes();
let res = write_file(context, &file_name, &content).await; write_file(context, &file_name, &content)
if res.is_err() { .await
error!(context, "Cannot write key to {}", file_name.display()); .with_context(|| format!("cannot write key to {}", file_name.display()))?;
} else {
context.emit_event(EventType::ImexFileWritten(file_name)); context.emit_event(EventType::ImexFileWritten(file_name));
} Ok(())
res
} }
#[cfg(test)] #[cfg(test)]
@@ -854,12 +850,12 @@ mod tests {
let context = TestContext::new_alice().await; let context = TestContext::new_alice().await;
let blobdir = context.ctx.get_blobdir(); let blobdir = context.ctx.get_blobdir();
if let Err(err) = imex(&context.ctx, ImexMode::ExportSelfKeys, blobdir, None).await { if let Err(err) = imex(&context.ctx, ImexMode::ExportSelfKeys, blobdir, None).await {
panic!("got error on export: {:?}", err); panic!("got error on export: {:#}", err);
} }
let context2 = TestContext::new_alice().await; let context2 = TestContext::new_alice().await;
if let Err(err) = imex(&context2.ctx, ImexMode::ImportSelfKeys, blobdir, None).await { if let Err(err) = imex(&context2.ctx, ImexMode::ImportSelfKeys, blobdir, None).await {
panic!("got error on import: {:?}", err); panic!("got error on import: {:#}", err);
} }
} }

View File

@@ -798,7 +798,14 @@ pub async fn remove_unused_files(context: &Context) -> Result<()> {
entry.file_name() entry.file_name()
); );
let path = entry.path(); let path = entry.path();
delete_file(context, path).await; if let Err(err) = delete_file(context, &path).await {
error!(
context,
"Failed to delete unused file {}: {:#}.",
path.display(),
err
);
}
} }
} }
Err(err) => { Err(err) => {

View File

@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
use std::str::from_utf8; use std::str::from_utf8;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use anyhow::{bail, Result}; use anyhow::{bail, Context as _, Result};
use chrono::{Local, TimeZone}; use chrono::{Local, TimeZone};
use futures::{StreamExt, TryStreamExt}; use futures::{StreamExt, TryStreamExt};
use mailparse::dateparse; use mailparse::dateparse;
@@ -369,49 +369,39 @@ pub(crate) async fn get_filebytes(context: &Context, path: impl AsRef<Path>) ->
Ok(meta.len()) Ok(meta.len())
} }
pub(crate) async fn delete_file(context: &Context, path: impl AsRef<Path>) -> bool { pub(crate) async fn delete_file(context: &Context, path: impl AsRef<Path>) -> Result<()> {
let path_abs = get_abs_path(context, &path); let path = path.as_ref();
let path_abs = get_abs_path(context, path);
if !path_abs.exists() { if !path_abs.exists() {
return false; bail!("path {} does not exist", path_abs.display());
} }
if !path_abs.is_file() { if !path_abs.is_file() {
warn!( warn!(context, "refusing to delete non-file {}.", path.display());
context, bail!("not a file: \"{}\"", path.display());
"refusing to delete non-file \"{}\".",
path.as_ref().display()
);
return false;
} }
let dpath = format!("{}", path.as_ref().to_string_lossy()); let dpath = format!("{}", path.to_string_lossy());
match fs::remove_file(path_abs).await { fs::remove_file(path_abs)
Ok(_) => { .await
.with_context(|| format!("cannot delete {:?}", dpath))?;
context.emit_event(EventType::DeletedBlobFile(dpath)); context.emit_event(EventType::DeletedBlobFile(dpath));
true Ok(())
}
Err(err) => {
warn!(context, "Cannot delete \"{}\": {}", dpath, err);
false
}
}
} }
pub async fn delete_files_in_dir(context: &Context, path: impl AsRef<Path>) { pub async fn delete_files_in_dir(context: &Context, path: impl AsRef<Path>) -> Result<()> {
match tokio::fs::read_dir(path).await { let read_dir = tokio::fs::read_dir(path)
Ok(read_dir) => { .await
.context("could not read dir to delete")?;
let mut read_dir = tokio_stream::wrappers::ReadDirStream::new(read_dir); let mut read_dir = tokio_stream::wrappers::ReadDirStream::new(read_dir);
while let Some(entry) = read_dir.next().await { while let Some(entry) = read_dir.next().await {
match entry { match entry {
Ok(file) => { Ok(file) => {
delete_file(context, file.file_name()).await; delete_file(context, file.file_name()).await?;
} }
Err(e) => warn!(context, "Could not read file to delete: {}", e), Err(e) => warn!(context, "Could not read file to delete: {}", e),
} }
} }
} Ok(())
Err(e) => warn!(context, "Could not read dir to delete: {}", e),
}
} }
pub(crate) async fn create_folder( pub(crate) async fn create_folder(
@@ -1047,7 +1037,9 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true";
}; };
} }
assert!(!delete_file(context, "$BLOBDIR/lkqwjelqkwlje").await); assert!(delete_file(context, "$BLOBDIR/lkqwjelqkwlje")
.await
.is_err());
assert!(write_file(context, "$BLOBDIR/foobar", b"content") assert!(write_file(context, "$BLOBDIR/foobar", b"content")
.await .await
.is_ok()); .is_ok());
@@ -1063,17 +1055,19 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true";
assert!(file_exist!(context, &abs_path)); assert!(file_exist!(context, &abs_path));
assert!(delete_file(context, "$BLOBDIR/foobar").await); assert!(delete_file(context, "$BLOBDIR/foobar").await.is_ok());
assert!(create_folder(context, "$BLOBDIR/foobar-folder") assert!(create_folder(context, "$BLOBDIR/foobar-folder")
.await .await
.is_ok()); .is_ok());
assert!(file_exist!(context, "$BLOBDIR/foobar-folder")); assert!(file_exist!(context, "$BLOBDIR/foobar-folder"));
assert!(!delete_file(context, "$BLOBDIR/foobar-folder").await); assert!(delete_file(context, "$BLOBDIR/foobar-folder")
.await
.is_err());
let fn0 = "$BLOBDIR/data.data"; let fn0 = "$BLOBDIR/data.data";
assert!(write_file(context, &fn0, b"content").await.is_ok()); assert!(write_file(context, &fn0, b"content").await.is_ok());
assert!(delete_file(context, &fn0).await); assert!(delete_file(context, &fn0).await.is_ok());
assert!(!file_exist!(context, &fn0)); assert!(!file_exist!(context, &fn0));
} }