Skip to content

Commit

Permalink
wip: fix shasum
Browse files Browse the repository at this point in the history
  • Loading branch information
delsner committed Aug 9, 2024
1 parent e7ffe6b commit 2937991
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 7 deletions.
21 changes: 20 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ tracing-log = "0.2"
url = "2.5.2"
fxhash = "0.2.1"
tempfile = "3.10.1"
walkdir = "2.5.0"
fs-set-times = "0.20.1"

[dev-dependencies]
async-std = "1.12.0"
Expand Down
52 changes: 46 additions & 6 deletions src/pack.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::{
collections::{HashMap, HashSet},
fs::FileTimes,
os::macos::fs::FileTimesExt,
path::{Path, PathBuf},
sync::Arc,
};
Expand All @@ -19,9 +21,11 @@ use rattler_lock::{CondaPackage, LockFile, Package};
use rattler_networking::{AuthenticationMiddleware, AuthenticationStorage};
use reqwest_middleware::ClientWithMiddleware;
use tokio_tar::Builder;
use walkdir::WalkDir;

use crate::{
get_size, PixiPackMetadata, ProgressReporter, CHANNEL_DIRECTORY_NAME, PIXI_PACK_METADATA_PATH,
get_size, util::set_default_file_times, PixiPackMetadata, ProgressReporter,
CHANNEL_DIRECTORY_NAME, PIXI_PACK_METADATA_PATH,
};
use anyhow::anyhow;

Expand Down Expand Up @@ -160,15 +164,34 @@ pub async fn pack(options: PackOptions) -> Result<()> {
// Add pixi-pack.json containing metadata.
tracing::info!("Creating pixi-pack.json file");
let metadata_path = output_folder.path().join(PIXI_PACK_METADATA_PATH);
let mut metadata_file = File::create(&metadata_path).await?;

let metadata = serde_json::to_string_pretty(&options.metadata)?;
metadata_file.write_all(metadata.as_bytes()).await?;
fs::write(metadata_path, metadata.as_bytes()).await?;

// Create environment file.
tracing::info!("Creating environment.yml file");
create_environment_file(output_folder.path(), conda_packages.iter().map(|(_, p)| p)).await?;

// Adjusting all timestamps of directories and files (excl. conda packages).
for entry in WalkDir::new(output_folder.path())
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.path() != output_folder.path())
{
match entry.path().extension().and_then(|e| e.to_str()) {
Some("tar.bz2") | Some("conda") => continue,
_ => {
set_default_file_times(entry.path()).map_err(|e| {
anyhow!(
"could not set default file times for path {}: {}",
entry.path().display(),
e
)
})?;
}
}
}

// Pack = archive the contents.
tracing::info!("Creating archive at {}", options.output_file.display());
archive_directory(output_folder.path(), &options.output_file)
Expand Down Expand Up @@ -240,6 +263,23 @@ async fn download_package(
dest.write_all(&chunk).await?;
}

// Adjust file metadata (timestamps).
let package_timestamp = package
.package_record()
.timestamp
.ok_or_else(|| anyhow!("could not read package timestamp"))?;
let file_times = FileTimes::new()
.set_modified(package_timestamp.into())
.set_accessed(package_timestamp.into())
.set_created(package_timestamp.into());

// Make sure to write all data and metadata to disk before modifying timestamp.
dest.sync_all().await?;
let dest_file = dest
.try_into_std()
.map_err(|e| anyhow!("could not read standard file: {:?}", e))?;
dest_file.set_times(file_times)?;

Ok(())
}

Expand Down Expand Up @@ -299,7 +339,7 @@ async fn create_environment_file(
environment.push_str(&format!(" - {}\n", match_spec_str));
}

fs::write(environment_path, environment)
fs::write(environment_path.as_path(), environment)
.await
.map_err(|e| anyhow!("Could not write environment file: {}", e))?;

Expand Down Expand Up @@ -343,7 +383,7 @@ async fn create_repodata_files(

let repodata_json = serde_json::to_string_pretty(&repodata)
.map_err(|e| anyhow!("could not serialize repodata: {}", e))?;
fs::write(repodata_path, repodata_json)
fs::write(repodata_path.as_path(), repodata_json)
.map_err(|e| anyhow!("could not write repodata: {}", e))
.await?;
}
Expand Down
22 changes: 22 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{path::Path, time::Duration};

use fs_set_times::{set_times, SystemTimeSpec};
use indicatif::{ProgressBar, ProgressStyle};

/// Progress reporter that wraps a progress bar with default styles.
Expand Down Expand Up @@ -30,3 +31,24 @@ pub fn get_size<P: AsRef<Path>>(path: P) -> std::io::Result<u64> {
}
Ok(size)
}

/// Set the modified, accessed, created time for a file.
pub fn set_default_file_times<P: AsRef<Path>>(path: P) -> std::io::Result<()> {
// TODO: This will only change the times for files not for directories.
// let file_default_time = std::time::SystemTime::UNIX_EPOCH;
// let file_times = FileTimes::new()
// .set_accessed(file_default_time)
// .set_modified(file_default_time);
// let dest = std::fs::File::open(path)?;
// dest.set_times(file_times)?;
println!("Changing times for {:?}", path.as_ref());
// TODO: Supposedly this external crate also supports changing mtime, atime for directories
// but it doesn't fix it.
set_times(
path,
Some(SystemTimeSpec::Absolute(std::time::SystemTime::UNIX_EPOCH)),
Some(SystemTimeSpec::Absolute(std::time::SystemTime::UNIX_EPOCH)),
)?;

Ok(())
}

0 comments on commit 2937991

Please sign in to comment.