mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-22 05:28:42 +00:00
Impl new fn atomic_install
for atommically installing a file
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
cc8144e06d
commit
7616546a61
1 changed files with 45 additions and 0 deletions
|
@ -1,4 +1,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::fs;
|
||||||
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
@ -8,6 +10,7 @@ use log::debug;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use reqwest::{Client, ClientBuilder, Method, Response};
|
use reqwest::{Client, ClientBuilder, Method, Response};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
use tinytemplate::TinyTemplate;
|
use tinytemplate::TinyTemplate;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -179,6 +182,48 @@ pub fn get_install_path<P: AsRef<Path>>(install_path: Option<P>) -> Option<PathB
|
||||||
dir
|
dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Atomically install a file.
|
||||||
|
///
|
||||||
|
/// This is a blocking function, must be called in `block_in_place` mode.
|
||||||
|
pub fn atomic_install(src: &Path, dst: &Path) -> io::Result<()> {
|
||||||
|
debug!(
|
||||||
|
"Attempting to atomically rename from '{}' to '{}'",
|
||||||
|
src.display(),
|
||||||
|
dst.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
if fs::rename(src, dst).is_err() {
|
||||||
|
debug!("Attempting at atomically failed, fallback to creating tempfile.");
|
||||||
|
// src and dst is not on the same filesystem/mountpoint.
|
||||||
|
// Fallback to creating NamedTempFile on the parent dir of
|
||||||
|
// dst.
|
||||||
|
|
||||||
|
let mut src_file = fs::File::open(src)?;
|
||||||
|
|
||||||
|
let parent = dst.parent().unwrap();
|
||||||
|
debug!("Creating named tempfile at '{}'", parent.display());
|
||||||
|
let mut tempfile = NamedTempFile::new_in(parent)?;
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Copying from '{}' to '{}'",
|
||||||
|
src.display(),
|
||||||
|
tempfile.path().display()
|
||||||
|
);
|
||||||
|
io::copy(&mut src_file, tempfile.as_file_mut())?;
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Persisting '{}' to '{}'",
|
||||||
|
tempfile.path().display(),
|
||||||
|
dst.display()
|
||||||
|
);
|
||||||
|
tempfile.persist(dst).map_err(io::Error::from)?;
|
||||||
|
} else {
|
||||||
|
debug!("Attempting at atomically succeeded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Template: Serialize {
|
pub trait Template: Serialize {
|
||||||
fn render(&self, template: &str) -> Result<String, BinstallError>
|
fn render(&self, template: &str) -> Result<String, BinstallError>
|
||||||
where
|
where
|
||||||
|
|
Loading…
Add table
Reference in a new issue