mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Download files to *.partial before renaming to final location
This commit is contained in:
@@ -23,7 +23,7 @@ pub fn default_log_location(context: LocationContext) -> PathBuf {
|
||||
if let Ok(locator) = auto_locate_app_manifest(context) {
|
||||
return locator.get_root_dir().join("Velopack.log");
|
||||
}
|
||||
|
||||
|
||||
warn!("Could not auto-locate app manifest, writing log to current directory.");
|
||||
|
||||
// If we can't locate the current app, we write to the current directory.
|
||||
@@ -149,7 +149,7 @@ impl VelopackLocator {
|
||||
pub fn get_temp_dir_root(&self) -> PathBuf {
|
||||
self.paths.PackagesDir.join("VelopackTemp")
|
||||
}
|
||||
|
||||
|
||||
/// Get the name of a new temporary directory inside get_temp_dir_root() with a random 16-character suffix.
|
||||
pub fn get_temp_dir_rand16(&self) -> PathBuf {
|
||||
self.get_temp_dir_root().join("tmp_".to_string() + &util::random_string(16))
|
||||
@@ -199,7 +199,7 @@ impl VelopackLocator {
|
||||
pub fn get_current_bin_dir_as_string(&self) -> String {
|
||||
Self::path_as_string(&self.paths.CurrentBinaryDir)
|
||||
}
|
||||
|
||||
|
||||
/// Returns a clone of the current app's manifest.
|
||||
pub fn get_manifest(&self) -> Manifest {
|
||||
self.manifest.clone()
|
||||
@@ -221,7 +221,7 @@ impl VelopackLocator {
|
||||
let ver = &self.manifest.version;
|
||||
format!("{}.{}.{}", ver.major, ver.minor, ver.patch)
|
||||
}
|
||||
|
||||
|
||||
/// Returns the current app package channel.
|
||||
pub fn get_manifest_channel(&self) -> String {
|
||||
self.manifest.channel.clone()
|
||||
@@ -391,7 +391,7 @@ pub fn auto_locate_app_manifest(context: LocationContext) -> Result<VelopackLoca
|
||||
match context {
|
||||
LocationContext::FromSpecifiedRootDir(dir) => search_path = dir.join("dummy"),
|
||||
LocationContext::FromSpecifiedAppExecutable(exe) => search_path = exe,
|
||||
_ => {},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let search_string = search_path.to_string_lossy();
|
||||
@@ -431,9 +431,9 @@ pub fn auto_locate_app_manifest(context: LocationContext) -> Result<VelopackLoca
|
||||
match context {
|
||||
LocationContext::FromSpecifiedRootDir(dir) => search_path = dir.join("dummy"),
|
||||
LocationContext::FromSpecifiedAppExecutable(exe) => search_path = exe,
|
||||
_ => {},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
let search_string = search_path.to_string_lossy();
|
||||
let idx = search_string.rfind(".app/");
|
||||
if idx.is_none() {
|
||||
@@ -469,14 +469,14 @@ pub fn auto_locate_app_manifest(context: LocationContext) -> Result<VelopackLoca
|
||||
CurrentBinaryDir: contents_dir,
|
||||
IsPortable: true,
|
||||
};
|
||||
|
||||
|
||||
config_to_locator(&config)
|
||||
}
|
||||
|
||||
fn read_current_manifest(nuspec_path: &PathBuf) -> Result<Manifest, Error> {
|
||||
if nuspec_path.exists() {
|
||||
if let Ok(nuspec) = util::retry_io(|| std::fs::read_to_string(&nuspec_path)) {
|
||||
return Ok(bundle::read_manifest_from_string(&nuspec)?);
|
||||
if let Ok(nuspec) = util::retry_io(|| std::fs::read_to_string(nuspec_path)) {
|
||||
return bundle::read_manifest_from_string(&nuspec);
|
||||
}
|
||||
}
|
||||
Err(Error::MissingNuspec)
|
||||
@@ -489,16 +489,15 @@ pub fn find_latest_full_package(packages_dir: &PathBuf) -> Option<(PathBuf, Mani
|
||||
info!("Attempting to auto-detect package in: {}", packages_dir);
|
||||
let mut package: Option<(PathBuf, Manifest)> = None;
|
||||
|
||||
if let Ok(paths) = glob::glob(format!("{}/*.nupkg", packages_dir).as_str()) {
|
||||
for path in paths {
|
||||
if let Ok(path) = path {
|
||||
trace!("Checking package: '{}'", path.to_string_lossy());
|
||||
if let Ok(mut bun) = bundle::load_bundle_from_file(&path) {
|
||||
if let Ok(mani) = bun.read_manifest() {
|
||||
if package.is_none() || mani.version > package.clone().unwrap().1.version {
|
||||
info!("Found {}: '{}'", mani.version, path.to_string_lossy());
|
||||
package = Some((path, mani));
|
||||
}
|
||||
let search_glob = format!("{}/*.nupkg", packages_dir);
|
||||
if let Ok(paths) = glob::glob(search_glob.as_str()) {
|
||||
for path in paths.into_iter().flatten() {
|
||||
trace!("Checking package: '{}'", path.to_string_lossy());
|
||||
if let Ok(mut bun) = bundle::load_bundle_from_file(&path) {
|
||||
if let Ok(mani) = bun.read_manifest() {
|
||||
if package.is_none() || mani.version > package.clone()?.1.version {
|
||||
info!("Found {}: '{}'", mani.version, path.to_string_lossy());
|
||||
package = Some((path, mani));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,36 +299,44 @@ impl UpdateManager {
|
||||
let packages_dir = &self.locator.get_packages_dir();
|
||||
|
||||
fs::create_dir_all(packages_dir)?;
|
||||
let target_file = packages_dir.join(name);
|
||||
let final_target_file = packages_dir.join(name);
|
||||
let partial_file = packages_dir.join(format!("{}.partial", name));
|
||||
|
||||
if target_file.exists() {
|
||||
info!("Package already exists on disk, skipping download: '{}'", target_file.to_string_lossy());
|
||||
if final_target_file.exists() {
|
||||
info!("Package already exists on disk, skipping download: '{}'", final_target_file.to_string_lossy());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let g = format!("{}/*.nupkg", packages_dir.to_string_lossy());
|
||||
info!("Searching for packages to clean in: '{}'", g);
|
||||
let old_nupkg_pattern = format!("{}/*.nupkg", packages_dir.to_string_lossy());
|
||||
let old_partial_pattern = format!("{}/*.partial", packages_dir.to_string_lossy());
|
||||
let mut to_delete = Vec::new();
|
||||
match glob::glob(&g) {
|
||||
Ok(paths) => {
|
||||
for path in paths {
|
||||
if let Ok(path) = path {
|
||||
to_delete.push(path.clone());
|
||||
debug!("Will delete: '{}'", path.to_string_lossy());
|
||||
|
||||
fn find_files_to_delete(pattern: &str, to_delete: &mut Vec<String>) {
|
||||
info!("Searching for packages to clean: '{}'", pattern);
|
||||
match glob::glob(pattern) {
|
||||
Ok(paths) => {
|
||||
for path in paths.into_iter().flatten() {
|
||||
to_delete.push(path.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error while searching for packages to clean: {}", e);
|
||||
Err(e) => {
|
||||
error!("Error while searching for packages to clean: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
find_files_to_delete(&old_nupkg_pattern, &mut to_delete);
|
||||
find_files_to_delete(&old_partial_pattern, &mut to_delete);
|
||||
|
||||
self.source.download_release_entry(&update.TargetFullRelease, &target_file.to_string_lossy(), progress)?;
|
||||
info!("Successfully placed file: '{}'", target_file.to_string_lossy());
|
||||
self.source.download_release_entry(&update.TargetFullRelease, &partial_file.to_string_lossy(), progress)?;
|
||||
info!("Successfully placed file: '{}'", partial_file.to_string_lossy());
|
||||
|
||||
info!("Renaming partial file to final target: '{}'", final_target_file.to_string_lossy());
|
||||
fs::rename(&partial_file, &final_target_file)?;
|
||||
|
||||
// extract new Update.exe on Windows only
|
||||
#[cfg(target_os = "windows")]
|
||||
match crate::bundle::load_bundle_from_file(&target_file) {
|
||||
match crate::bundle::load_bundle_from_file(&final_target_file) {
|
||||
Ok(bundle) => {
|
||||
info!("Bundle loaded successfully.");
|
||||
let update_exe_path = self.locator.get_update_path();
|
||||
@@ -342,7 +350,7 @@ impl UpdateManager {
|
||||
}
|
||||
|
||||
for path in to_delete {
|
||||
info!("Cleaning up old package: '{}'", path.to_string_lossy());
|
||||
info!("Deleting up old package: '{}'", path);
|
||||
let _ = fs::remove_file(&path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user