use std::fs::File;
use std::io::Read as _;
use camino::Utf8Path;
use camino::Utf8PathBuf;
use miette::Context as _;
use miette::IntoDiagnostic as _;
use miette::Result;
use std::fs;
use xxhash_rust::xxh3::Xxh3;
pub fn compute_checksum_for_files(paths: &[&Utf8Path]) -> Result<String> {
let mut hasher = Xxh3::new();
let mut buffer = [0; 8192];
for path in paths {
if let Ok(mut file) = File::open(path) {
loop {
let bytes_read = file
.read(&mut buffer)
.into_diagnostic()
.wrap_err_with(|| format!("while reading file {path:?}"))?;
if bytes_read == 0 {
break;
}
hasher.update(&buffer[..bytes_read]);
}
} else {
// If file doesn't exist or cannot be opened, consider it as an empty file
let empty_data: &[u8] = &[];
hasher.update(empty_data);
}
}
let result = hasher.digest128();
Ok(format!("{:x}", result))
}
pub fn install_tracing() {
use tracing_error::ErrorLayer;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{fmt, EnvFilter};
let fmt_layer = fmt::layer()
.pretty()
.with_target(false)
.with_writer(std::io::stderr);
let filter_layer = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info"))
.unwrap();
tracing_subscriber::registry()
.with(filter_layer)
.with(fmt_layer)
.with(ErrorLayer::default())
.init();
}
pub fn load_manifest() -> Result<(Utf8PathBuf, toml_edit::Document)> {
// Identify path to manifest from cargo-px
let manifest_path =
Utf8PathBuf::try_from(cargo_px_env::generated_pkg_manifest_path().into_diagnostic()?)
.into_diagnostic()?;
// Read the contents of the Cargo.toml file
let toml_content = fs::read_to_string(&manifest_path).into_diagnostic()?;
// Parse it
toml_content
.parse::<toml_edit::Document>()
.map(|manifest| (manifest_path, manifest))
.into_diagnostic()
}
pub fn save_manifest(manifest: toml_edit::Document) -> Result<()> {
// Identify path to manifest from cargo-px
let path =
Utf8PathBuf::try_from(cargo_px_env::generated_pkg_manifest_path().into_diagnostic()?)
.into_diagnostic()?;
fs::write(path, manifest.to_string()).into_diagnostic()
}