Only write to files if they don't exist or their existing contents differs from the new contents

This commit is contained in:
Tony Garnock-Jones 2021-07-14 11:53:12 +02:00
parent 7712c6e0a9
commit 6d9ed94065
1 changed files with 32 additions and 21 deletions

View File

@ -20,10 +20,9 @@ use preserves::value::Set;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fs::DirBuilder; use std::fs::DirBuilder;
use std::fs::File; use std::fs::File;
use std::io;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::Read;
use std::io::Error;
use std::io::ErrorKind;
use std::io::Write; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
@ -52,7 +51,7 @@ impl CompilerConfig {
} }
} }
pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>) -> Result<(), Error> { pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>) -> io::Result<()> {
for i in inputs { for i in inputs {
let mut f = File::open(&i)?; let mut f = File::open(&i)?;
let mut src = IOBinarySource::new(&mut f); let mut src = IOBinarySource::new(&mut f);
@ -61,9 +60,11 @@ impl CompilerConfig {
if let Ok(s) = Schema::try_from(&blob) { if let Ok(s) = Schema::try_from(&blob) {
let prefix = i.file_stem().ok_or_else( let prefix = i.file_stem().ok_or_else(
|| Error::new(ErrorKind::InvalidData, format!("Bad schema file stem: {:?}", i)))? || io::Error::new(io::ErrorKind::InvalidData,
format!("Bad schema file stem: {:?}", i)))?
.to_str().ok_or_else( .to_str().ok_or_else(
|| Error::new(ErrorKind::InvalidData, format!("Invalid UTF-8 in schema file name: {:?}", i)))?; || io::Error::new(io::ErrorKind::InvalidData,
format!("Invalid UTF-8 in schema file name: {:?}", i)))?;
self.bundle.insert(vec![prefix.to_owned()], s); self.bundle.insert(vec![prefix.to_owned()], s);
continue; continue;
} }
@ -75,24 +76,38 @@ impl CompilerConfig {
continue; continue;
} }
return Err(Error::new(ErrorKind::InvalidData, return Err(io::Error::new(io::ErrorKind::InvalidData,
format!("Invalid schema binary blob {:?}", i))); format!("Invalid schema binary blob {:?}", i)));
} }
Ok(()) Ok(())
} }
} }
pub fn expand_inputs(globs: &Vec<String>) -> Result<Vec<PathBuf>, Error> { pub fn expand_inputs(globs: &Vec<String>) -> io::Result<Vec<PathBuf>> {
let mut result = Vec::new(); let mut result = Vec::new();
for g in globs.iter() { for g in globs.iter() {
for p in glob(g).map_err(|e| Error::new(ErrorKind::InvalidData, format!("{}", e)))? { for p in glob(g).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("{}", e)))? {
result.push(p.map_err(glob::GlobError::into_error)?) result.push(p.map_err(glob::GlobError::into_error)?)
} }
} }
Ok(result) Ok(result)
} }
pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> { fn write_if_changed(output_path: &PathBuf, contents: &[u8]) -> io::Result<()> {
if output_path.exists() {
if let Ok(mut f) = File::open(output_path) {
let mut existing_contents = Vec::new();
f.read_to_end(&mut existing_contents)?;
if existing_contents == contents {
return Ok(());
}
}
}
let mut f = File::create(output_path)?;
f.write_all(contents)
}
pub fn compile(config: &CompilerConfig) -> io::Result<()> {
for (k, v) in config.bundle.iter() { for (k, v) in config.bundle.iter() {
let mut output_path = config.output_dir.clone(); let mut output_path = config.output_dir.clone();
output_path.extend(k); output_path.extend(k);
@ -174,10 +189,8 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
} }
{ {
let mut f = File::create(&output_path)?; let contents = lines.join("\n");
for line in lines { write_if_changed(&output_path, contents.as_bytes())?;
write!(f, "{}\n", line)?;
}
} }
{ {
@ -186,14 +199,12 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
let mut lines = if !mod_rs.exists() { let mut lines = if !mod_rs.exists() {
Set::new() Set::new()
} else { } else {
BufReader::new(File::open(&mod_rs)?) io::BufReader::new(File::open(&mod_rs)?)
.lines().collect::<Result<Set<String>, Error>>()? .lines().collect::<Result<Set<String>, _>>()?
}; };
lines.insert(format!("pub mod {};", &module_name)); lines.insert(format!("pub mod {};", &module_name));
let mut f = File::create(mod_rs)?; let contents = lines.into_iter().collect::<Vec<String>>().join("\n");
for line in lines { write_if_changed(&mod_rs, contents.as_bytes())?;
write!(f, "{}\n", line)?;
}
} }
} }
Ok(()) Ok(())