pray-core 1.13.0

Core library for Prayfile, the package manager for the language placed before inference
Documentation
use super::*;

pub fn resolve_project_in_context(
    manifest_path: &Path,
    project_root: &Path,
    options: &ResolveOptions,
) -> PrayResult<ResolvedProject> {
    let manifest_text = crate::manifest::read_manifest_text(manifest_path)?;
    let manifest = crate::manifest::parse_manifest(&manifest_text)?;
    resolve_manifest_in_context(manifest_path, project_root, manifest, options)
}

pub fn resolve_manifest_in_context(
    manifest_path: &Path,
    project_root: &Path,
    manifest: Manifest,
    options: &ResolveOptions,
) -> PrayResult<ResolvedProject> {
    let user_config = crate::config::load_user_config()?;
    let lockfile_path = project_root.join("Prayfile.lock");
    let lockfile_hints = crate::lockfile::read_lockfile(&lockfile_path).ok();
    crate::environment::validate_environment(&manifest, options.environment.as_deref())?;
    let manifest_hash = manifest.manifest_hash()?;
    let sources = source_map(&manifest.sources);
    let git_sources = prepare_git_sources(
        project_root,
        &manifest.sources,
        lockfile_hints.as_ref(),
        options,
    )?;
    let source_host_keys = prepare_pray_ssh_host_keys(&manifest.sources)?;
    let mut queue = crate::resolve_queue::ResolveQueue::seed(&manifest.packages)?;
    let outcome = queue.resolve_all(&manifest.packages, &sources, |declaration| {
        resolve_package(
            project_root,
            &sources,
            &git_sources,
            &user_config,
            declaration,
            lockfile_hints.as_ref(),
            options,
        )
    });
    if !outcome.errors.is_empty() {
        let message = outcome.errors.join("\n");
        return Err(if outcome.saw_network_error {
            PrayError::Network(message)
        } else {
            PrayError::Resolution(message)
        });
    }
    let packages = outcome.packages;
    let mut local_files = Vec::new();
    let mut local_errors = Vec::new();
    for local in &manifest.local {
        match resolve_local_file(project_root, local) {
            Ok(resolved) => local_files.push(resolved),
            Err(error) => local_errors.push(format!("local {}: {error}", local.path)),
        }
    }
    if !local_errors.is_empty() {
        return Err(PrayError::Resolution(local_errors.join("\n")));
    }
    crate::resolve_deps::reject_dependency_cycles(&packages)?;
    Ok(ResolvedProject {
        manifest_path: manifest_path.to_path_buf(),
        project_root: project_root.to_path_buf(),
        manifest,
        manifest_hash,
        packages,
        local_files,
        source_revisions: git_sources
            .into_iter()
            .filter_map(|(name, checkout)| {
                if checkout.revision.is_empty() {
                    None
                } else {
                    Some((name, checkout.revision))
                }
            })
            .collect(),
        source_host_keys,
        environment: options.environment.clone(),
    })
}