diff --git a/prost-build/src/config.rs b/prost-build/src/config.rs index 0c3c6a75b..861a7de7c 100644 --- a/prost-build/src/config.rs +++ b/prost-build/src/config.rs @@ -806,30 +806,22 @@ impl Config { .expect("every module should have a filename"); let output_path = target.join(file_name); - let previous_content = fs::read(&output_path); - - if previous_content - .map(|previous_content| previous_content == content.as_bytes()) - .unwrap_or(false) - { - trace!("unchanged: {:?}", file_name); - } else { - trace!("writing: {:?}", file_name); - fs::write(output_path, content)?; - } + write_file_if_changed(&output_path, content.as_bytes())?; } if let Some(ref include_file) = self.include_file { - trace!("Writing include file: {:?}", target.join(include_file)); - let mut file = fs::File::create(target.join(include_file))?; - self.write_line(&mut file, 0, "// This file is @generated by prost-build.")?; + let path = target.join(include_file); + trace!("Writing include file: {:?}", path); + let mut buffer = Vec::new(); + self.write_line(&mut buffer, 0, "// This file is @generated by prost-build.")?; self.write_includes( modules.keys().collect(), - &mut file, + &mut buffer, if target_is_env { None } else { Some(&target) }, &file_names, )?; - file.flush()?; + + write_file_if_changed(&path, &buffer)?; } Ok(()) @@ -1072,6 +1064,26 @@ impl Config { } } +/// Write a slice as the entire contents of a file. +/// +/// This function will create a file if it does not exist, +/// and will entirely replace its contents if it does. When +/// the contents is already correct, it doesn't touch to the file. +fn write_file_if_changed(path: &Path, content: &[u8]) -> std::io::Result<()> { + let previous_content = fs::read(path); + + if previous_content + .map(|previous_content| previous_content == content) + .unwrap_or(false) + { + trace!("unchanged: {:?}", path); + Ok(()) + } else { + trace!("writing: {:?}", path); + fs::write(path, content) + } +} + impl default::Default for Config { fn default() -> Config { Config {