Skip to content

Commit

Permalink
adjust some names, add some docs
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Jul 4, 2023
1 parent 67d6aef commit be811a5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
7 changes: 0 additions & 7 deletions crates/rattler-bin/src/commands/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,6 @@ pub async fn create(opt: Opt) -> anyhow::Result<()> {

// sort topologically
let required_packages = PackageRecord::sort_topologically(required_packages);
// println!("required_packages: {:#?}", required_packages);
for pkg in &required_packages {
println!(
"{}-{}-{}",
pkg.package_record.name, pkg.package_record.version, pkg.package_record.build
);
}

// Construct a transaction to
let transaction = Transaction::from_current_and_desired(
Expand Down
11 changes: 10 additions & 1 deletion crates/rattler_conda_types/src/repo_data/topological_sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use fxhash::{FxHashMap, FxHashSet};
/// This function is deterministic, meaning that it will return the same result regardless of the
/// order of `packages` and of the `depends` vector inside the records.
///
/// If cycles are encountered, and one of the packages in the cycle is noarch, the noarch package
/// is sorted _after_ the other packages in the cycle. This is done to ensure that the noarch
/// package is installed last, so that it can be linked correctly (ie. compiled with Python if
/// necessary).
///
/// Note that this function only works for packages with unique names.
pub fn sort_topologically<T: AsRef<PackageRecord> + Clone>(packages: Vec<T>) -> Vec<T> {
let roots = get_graph_roots(&packages, None);
Expand Down Expand Up @@ -44,7 +49,9 @@ pub fn sort_topologically<T: AsRef<PackageRecord> + Clone>(packages: Vec<T>) ->
get_topological_order(roots, &mut all_packages, &cycle_breaks)
}

/// Retrieves the names of the packages that form the roots of the graph
/// Retrieves the names of the packages that form the roots of the graph and breaks specified
/// cycles (e.g. if there is a cycle between A and B and there is a cycle_break (A, B), the edge
/// A -> B will be removed)
fn get_graph_roots<T: AsRef<PackageRecord>>(
records: &[T],
cycle_breaks: Option<&FxHashSet<(String, String)>>,
Expand Down Expand Up @@ -113,6 +120,8 @@ fn find_cycles<T: AsRef<PackageRecord>>(
None
}

/// Breaks cycles by removing the edges that form them
/// Edges from arch to noarch packages are removed to break the cycles.
fn break_cycles<T: AsRef<PackageRecord>>(
cycles: Vec<Vec<String>>,
packages: &FxHashMap<String, T>,
Expand Down
25 changes: 16 additions & 9 deletions crates/rattler_repodata_gateway/src/sparse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ struct SparseRepoDataInner {

impl SparseRepoData {
/// Construct an instance of self from a file on disk and a [`Channel`].
/// The `patch_function` can be used to patch the package record after it has been parsed
/// (e.g. to add `pip` to `python`).
pub fn new(
channel: Channel,
subdir: impl Into<String>,
Expand Down Expand Up @@ -196,7 +198,7 @@ fn parse_records<'i>(
packages: &[(PackageFilename<'i>, &'i RawValue)],
channel: &Channel,
subdir: &str,
patch_record_fn: Option<fn(&mut PackageRecord)>,
patch_function: Option<fn(&mut PackageRecord)>,
) -> io::Result<Vec<RepoDataRecord>> {
let channel_name = channel.canonical_name();

Expand All @@ -220,7 +222,7 @@ fn parse_records<'i>(
}

// Apply the patch function if one was specified
if let Some(patch_fn) = patch_record_fn {
if let Some(patch_fn) = patch_function {
for record in &mut result {
patch_fn(&mut record.package_record);
}
Expand All @@ -230,27 +232,32 @@ fn parse_records<'i>(
}

/// A helper function that immediately loads the records for the given packages (and their dependencies).
/// Records for the specified packages are loaded from the repodata files.
/// The patch_record_fn is applied to each record after it has been parsed and can mutate the record after
/// it has been loaded.
pub async fn load_repo_data_recursively(
repo_data_paths: impl IntoIterator<Item = (Channel, impl Into<String>, impl AsRef<Path>)>,
package_names: impl IntoIterator<Item = impl Into<String>>,
patch_record_fn: Option<fn(&mut PackageRecord)>,
patch_function: Option<fn(&mut PackageRecord)>,
) -> Result<Vec<Vec<RepoDataRecord>>, io::Error> {
// Open the different files and memory map them to get access to their bytes. Do this in parallel.
let lazy_repo_data = stream::iter(repo_data_paths)
.map(|(channel, subdir, path)| {
let path = path.as_ref().to_path_buf();
let subdir = subdir.into();
tokio::task::spawn_blocking(move || SparseRepoData::new(channel, subdir, path, None))
.unwrap_or_else(|r| match r.try_into_panic() {
Ok(panic) => std::panic::resume_unwind(panic),
Err(err) => Err(io::Error::new(io::ErrorKind::Other, err.to_string())),
})
tokio::task::spawn_blocking(move || {
SparseRepoData::new(channel, subdir, path, patch_function)
})
.unwrap_or_else(|r| match r.try_into_panic() {
Ok(panic) => std::panic::resume_unwind(panic),
Err(err) => Err(io::Error::new(io::ErrorKind::Other, err.to_string())),
})
})
.buffered(50)
.try_collect::<Vec<_>>()
.await?;

SparseRepoData::load_records_recursive(&lazy_repo_data, package_names, patch_record_fn)
SparseRepoData::load_records_recursive(&lazy_repo_data, package_names, patch_function)
}

fn deserialize_filename_and_raw_record<'d, D: Deserializer<'d>>(
Expand Down

0 comments on commit be811a5

Please sign in to comment.