Skip to content

Commit

Permalink
fix: parallel downloads order (#133)
Browse files Browse the repository at this point in the history
- Now that downloads happen in parallel, we must be sure to order the
download results (zip url and hash) in a consistent order

- Fix hardcoded forge-std version
  • Loading branch information
beeb committed Aug 7, 2024
1 parent 1993de3 commit baad1bf
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
7 changes: 7 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ pub fn get_config_path() -> Result<PathBuf> {
}
}

/// Read the list of dependencies from the config file
///
/// If no config file path is provided, then the path is inferred automatically
/// The returned list is sorted by name and version
pub fn read_config_deps(path: Option<PathBuf>) -> Result<Vec<Dependency>> {
let path: PathBuf = match path {
Some(p) => p,
Expand All @@ -270,6 +274,9 @@ pub fn read_config_deps(path: Option<PathBuf>) -> Result<Vec<Dependency>> {
for (name, v) in data {
dependencies.push(parse_dependency(name, v)?);
}
dependencies
.sort_unstable_by(|a, b| a.name().cmp(b.name()).then_with(|| a.version().cmp(b.version())));

Ok(dependencies)
}

Expand Down
32 changes: 23 additions & 9 deletions src/dependency_downloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use yansi::Paint as _;

pub type Result<T> = std::result::Result<T, DownloadError>;

/// Download the dependencies from the list in parallel
///
/// Note: the dependencies list should be sorted by name and version
pub async fn download_dependencies(
dependencies: &[Dependency],
clean: bool,
Expand All @@ -39,15 +42,17 @@ pub async fn download_dependencies(
let mut set = JoinSet::new();
for dep in dependencies {
set.spawn({
let dep = dep.clone();
async move { download_dependency(&dep, true).await }
let d = dep.clone();
async move { download_dependency(&d, true).await }
});
}

let mut results = Vec::<DownloadResult>::new();
let mut results = Vec::new();
while let Some(res) = set.join_next().await {
results.push(res??);
}
// sort to make the order consistent with the input dependencies list (which should be sorted)
results.sort_unstable_by(|a, b| a.name.cmp(&b.name).then_with(|| a.version.cmp(&b.version)));

Ok(results)
}
Expand All @@ -66,6 +71,8 @@ pub fn unzip_dependencies(dependencies: &[Dependency]) -> Result<()> {

#[derive(Debug, Clone)]
pub struct DownloadResult {
pub name: String,
pub version: String,
pub hash: String,
pub url: String,
}
Expand Down Expand Up @@ -93,17 +100,24 @@ pub async fn download_dependency(
None => get_dependency_url_remote(dependency).await?,
};
download_via_http(&url, dep, &dependency_directory).await?;
DownloadResult { hash: sha256_digest(dep), url }
DownloadResult {
name: dep.name.clone(),
version: dep.version.clone(),
hash: sha256_digest(dep),
url,
}
}
Dependency::Git(dep) => {
let hash = download_via_git(dep, &dependency_directory).await?;
DownloadResult { hash, url: dep.git.clone() }
DownloadResult {
name: dep.name.clone(),
version: dep.version.clone(),
hash,
url: dep.git.clone(),
}
}
};
println!(
"{}",
format!("Dependency {}-{} downloaded!", dependency.name(), dependency.version()).green()
);
println!("{}", format!("Dependency {dependency} downloaded!").green());

Ok(res)
}
Expand Down
19 changes: 14 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,9 +1021,8 @@ libs = ["dependencies"]
}
}

let path_dependency = DEPENDENCY_DIR.join("forge-std-1.9.1");
let lock_test = get_current_working_dir().join("test").join("soldeer.lock");
assert!(path_dependency.exists());
assert!(find_forge_std_path().exists());
assert!(lock_test.exists());
clean_test_env(target_config);
}
Expand All @@ -1037,14 +1036,12 @@ libs = ["dependencies"]
let submodules_path = get_current_working_dir().join(".gitmodules");
let lib_path = get_current_working_dir().join("lib");

let path_dependency = DEPENDENCY_DIR.join("forge-std-1.9.1");
let lock_test = get_current_working_dir().join("test").join("soldeer.lock");

//remove it just in case
let _ = remove_file(&submodules_path);
let _ = remove_dir_all(&lib_path);
let _ = remove_file(&lock_test);
let _ = remove_dir_all(&path_dependency);

let mut file: std::fs::File =
fs::OpenOptions::new().create_new(true).write(true).open(&submodules_path).unwrap();
Expand Down Expand Up @@ -1073,7 +1070,7 @@ libs = ["dependencies"]
}
}

assert!(path_dependency.exists());
assert!(find_forge_std_path().exists());
assert!(lock_test.exists());
assert!(!submodules_path.exists());
assert!(!lib_path.exists());
Expand Down Expand Up @@ -1131,4 +1128,16 @@ libs = ["dependencies"]
}
String::from(target.to_str().unwrap())
}

fn find_forge_std_path() -> PathBuf {
for entry in fs::read_dir(DEPENDENCY_DIR.clone()).unwrap().filter_map(Result::ok) {
let path = entry.path();
if path.is_dir() &&
path.file_name().unwrap().to_string_lossy().starts_with("forge-std-")
{
return path;
}
}
panic!("could not find forge-std folder in dependency dir");
}
}

0 comments on commit baad1bf

Please sign in to comment.