make failure to preserve metadata a hard error
This commit is contained in:
parent
557bd1520a
commit
00013460a7
1 changed files with 81 additions and 33 deletions
114
src/lib.rs
114
src/lib.rs
|
|
@ -332,14 +332,13 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
||||||
opt_metadata_preserved = input_path
|
opt_metadata_preserved = input_path
|
||||||
.metadata()
|
.metadata()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
// TODO: Fail if input and output file are the same and metadata cannot be preserved?
|
// Fail if metadata cannot be preserved
|
||||||
warn!(
|
PngError::new(&format!(
|
||||||
"Unable to read metadata from input file {:?}: {}",
|
"Unable to read metadata from input file {:?}: {}",
|
||||||
input_path, err
|
input_path, err
|
||||||
);
|
))
|
||||||
err
|
|
||||||
})
|
})
|
||||||
.ok();
|
.map(Some)?;
|
||||||
debug!("preserving metadata: {:?}", opt_metadata_preserved);
|
debug!("preserving metadata: {:?}", opt_metadata_preserved);
|
||||||
} else {
|
} else {
|
||||||
opt_metadata_preserved = None;
|
opt_metadata_preserved = None;
|
||||||
|
|
@ -404,7 +403,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
if let Some(metadata_input) = &opt_metadata_preserved {
|
if let Some(metadata_input) = &opt_metadata_preserved {
|
||||||
copy_permissions(&metadata_input, &out_file);
|
copy_permissions(&metadata_input, &out_file)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buffer = BufWriter::new(out_file);
|
let mut buffer = BufWriter::new(out_file);
|
||||||
|
|
@ -422,7 +421,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
||||||
// force drop and thereby closing of file handle before modifying any timestamp
|
// force drop and thereby closing of file handle before modifying any timestamp
|
||||||
std::mem::drop(buffer);
|
std::mem::drop(buffer);
|
||||||
if let Some(metadata_input) = &opt_metadata_preserved {
|
if let Some(metadata_input) = &opt_metadata_preserved {
|
||||||
copy_times(&metadata_input, &output_path);
|
copy_times(&metadata_input, &output_path)?;
|
||||||
}
|
}
|
||||||
info!("Output: {}", output_path.display());
|
info!("Output: {}", output_path.display());
|
||||||
}
|
}
|
||||||
|
|
@ -960,49 +959,98 @@ fn perform_backup(input_path: &Path) -> PngResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
fn copy_permissions(metadata_input: &Metadata, out_file: &File) {
|
fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()> {
|
||||||
if let Ok(out_meta) = out_file.metadata() {
|
let readonly_input = metadata_input.permissions().readonly();
|
||||||
let readonly = metadata_input.permissions().readonly();
|
|
||||||
out_meta.permissions().set_readonly(readonly);
|
out_file
|
||||||
return;
|
.metadata()
|
||||||
}
|
.map_err(|err_io| {
|
||||||
warn!("Failed to set permissions on output file");
|
PngError::new(&format!(
|
||||||
|
"unable to read filesystem metadata of output file: {}",
|
||||||
|
err_io
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.and_then(|out_meta| {
|
||||||
|
out_meta.permissions().set_readonly(readonly_input);
|
||||||
|
out_file
|
||||||
|
.metadata()
|
||||||
|
.map_err(|err_io| {
|
||||||
|
PngError::new(&format!(
|
||||||
|
"unable to re-read filesystem metadata of output file: {}",
|
||||||
|
err_io
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.and_then(|out_meta_reread| {
|
||||||
|
if out_meta_reread.permissions().readonly() != readonly_input {
|
||||||
|
Err(PngError::new(&format!(
|
||||||
|
"failed to set readonly, expected: {}, found: {}",
|
||||||
|
readonly_input,
|
||||||
|
out_meta_reread.permissions().readonly()
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn copy_permissions(metadata_input: &Metadata, out_file: &File) {
|
fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()> {
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
let permissions = metadata_input.permissions().mode();
|
let permissions = metadata_input.permissions().mode();
|
||||||
if let Ok(out_meta) = out_file.metadata() {
|
|
||||||
out_meta.permissions().set_mode(permissions);
|
out_file
|
||||||
if let Ok(out_meta_reread) = out_file.metadata() {
|
.metadata()
|
||||||
if out_meta_reread.permissions().mode() != permissions {
|
.map_err(|err_io| {
|
||||||
warn!("Failed to set input file permissions on output file");
|
PngError::new(&format!(
|
||||||
}
|
"unable to read filesystem metadata of output file: {}",
|
||||||
} else {
|
err_io
|
||||||
warn!("Failed to read newly-set permissions on output file");
|
))
|
||||||
}
|
})
|
||||||
return;
|
.and_then(|out_meta| {
|
||||||
}
|
out_meta.permissions().set_mode(permissions);
|
||||||
warn!("Failed to set permissions on output file");
|
out_file
|
||||||
|
.metadata()
|
||||||
|
.map_err(|err_io| {
|
||||||
|
PngError::new(&format!(
|
||||||
|
"unable to re-read filesystem metadata of output file: {}",
|
||||||
|
err_io
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.and_then(|out_meta_reread| {
|
||||||
|
if out_meta_reread.permissions().mode() != permissions {
|
||||||
|
Err(PngError::new(&format!(
|
||||||
|
"failed to set permissions, expected: {:04o}, found: {:04o}",
|
||||||
|
permissions,
|
||||||
|
out_meta_reread.permissions().mode()
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "filetime"))]
|
#[cfg(not(feature = "filetime"))]
|
||||||
fn copy_times(_: &Metadata, _: &Path) {}
|
fn copy_times(_: &Metadata, _: &Path) -> PngResult<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "filetime")]
|
#[cfg(feature = "filetime")]
|
||||||
fn copy_times(input_path_meta: &Metadata, out_path: &Path) {
|
fn copy_times(input_path_meta: &Metadata, out_path: &Path) -> PngResult<()> {
|
||||||
let atime = filetime::FileTime::from_last_access_time(input_path_meta);
|
let atime = filetime::FileTime::from_last_access_time(input_path_meta);
|
||||||
let mtime = filetime::FileTime::from_last_modification_time(input_path_meta);
|
let mtime = filetime::FileTime::from_last_modification_time(input_path_meta);
|
||||||
debug!(
|
debug!(
|
||||||
"attempting to set file times: atime: {:?}, mtime: {:?}",
|
"attempting to set file times: atime: {:?}, mtime: {:?}",
|
||||||
atime, mtime
|
atime, mtime
|
||||||
);
|
);
|
||||||
if let Err(err) = filetime::set_file_times(out_path, atime, mtime) {
|
filetime::set_file_times(out_path, atime, mtime).map_err(|err_io| {
|
||||||
warn!("Failed to set input file access/modification time on output file");
|
PngError::new(&format!(
|
||||||
debug!("Error: {:?}", err);
|
"unable to set file times on {:?}: {}",
|
||||||
}
|
out_path, err_io
|
||||||
|
))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compares images pixel by pixel for equivalent content
|
/// Compares images pixel by pixel for equivalent content
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue