pesde/src/lockfile.rs

138 lines
4.1 KiB
Rust
Raw Normal View History

2024-07-12 23:09:37 +01:00
use crate::{
2024-07-24 10:55:15 +01:00
manifest::{
overrides::OverrideKey,
target::{Target, TargetKind},
DependencyType,
},
2024-07-12 23:09:37 +01:00
names::{PackageName, PackageNames},
2024-07-28 17:19:54 +01:00
source::{
refs::PackageRefs, specifiers::DependencySpecifiers, traits::PackageRef,
version_id::VersionId,
},
2024-07-12 23:09:37 +01:00
};
use relative_path::RelativePathBuf;
2024-07-12 23:09:37 +01:00
use semver::Version;
use serde::{Deserialize, Serialize};
2024-07-17 18:38:01 +01:00
use std::{
collections::{btree_map::Entry, BTreeMap},
path::{Path, PathBuf},
};
2024-08-03 21:18:38 +01:00
/// A graph of dependencies
2024-07-22 22:16:04 +01:00
pub type Graph<Node> = BTreeMap<PackageNames, BTreeMap<VersionId, Node>>;
2024-07-12 23:09:37 +01:00
2024-08-03 21:18:38 +01:00
/// A dependency graph node
2024-07-12 23:09:37 +01:00
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DependencyGraphNode {
2024-08-03 21:18:38 +01:00
/// The alias and specifiers for the dependency, if it is a direct dependency (i.e. used by the current project)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub direct: Option<(String, DependencySpecifiers)>,
2024-08-03 21:18:38 +01:00
/// The dependencies of the package
2024-07-22 21:00:09 +01:00
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
2024-07-22 22:16:04 +01:00
pub dependencies: BTreeMap<PackageNames, (VersionId, String)>,
2024-08-03 21:18:38 +01:00
/// The type of the dependency
pub ty: DependencyType,
2024-08-03 21:18:38 +01:00
/// The package reference
2024-07-22 22:16:04 +01:00
pub pkg_ref: PackageRefs,
}
2024-07-17 18:38:01 +01:00
impl DependencyGraphNode {
pub(crate) fn base_folder(&self, project_target: TargetKind) -> String {
if self.pkg_ref.use_new_structure() {
self.pkg_ref.target_kind().packages_folder(&project_target)
2024-07-17 18:38:01 +01:00
} else {
"..".to_string()
}
}
2024-08-03 21:18:38 +01:00
/// Returns the folder to store the contents of the package in
2024-07-17 18:38:01 +01:00
pub fn container_folder<P: AsRef<Path>>(
&self,
path: &P,
name: &PackageNames,
version: &Version,
) -> PathBuf {
path.as_ref()
.join(name.escaped())
.join(version.to_string())
.join(name.as_str().1)
}
}
2024-08-03 21:18:38 +01:00
/// A graph of `DependencyGraphNode`s
2024-07-17 18:38:01 +01:00
pub type DependencyGraph = Graph<DependencyGraphNode>;
pub(crate) fn insert_node(
graph: &mut DependencyGraph,
name: PackageNames,
2024-07-22 22:16:04 +01:00
version: VersionId,
mut node: DependencyGraphNode,
is_top_level: bool,
) {
2024-07-23 23:53:34 +01:00
if !is_top_level && node.direct.take().is_some() {
log::debug!(
"tried to insert {name}@{version} as direct dependency from a non top-level context",
);
}
match graph
.entry(name.clone())
.or_default()
.entry(version.clone())
{
Entry::Vacant(entry) => {
entry.insert(node);
}
Entry::Occupied(existing) => {
let current_node = existing.into_mut();
2024-07-12 23:09:37 +01:00
match (&current_node.direct, &node.direct) {
(Some(_), Some(_)) => {
log::warn!("duplicate direct dependency for {name}@{version}",);
}
(None, Some(_)) => {
current_node.direct = node.direct;
}
(_, _) => {}
}
}
}
2024-07-12 23:09:37 +01:00
}
2024-08-03 21:18:38 +01:00
/// A downloaded dependency graph node, i.e. a `DependencyGraphNode` with a `Target`
2024-07-17 18:38:01 +01:00
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DownloadedDependencyGraphNode {
2024-08-03 21:18:38 +01:00
/// The target of the package
2024-07-17 18:38:01 +01:00
pub target: Target,
2024-08-03 21:18:38 +01:00
/// The node
2024-07-22 22:16:04 +01:00
#[serde(flatten)]
pub node: DependencyGraphNode,
2024-07-17 18:38:01 +01:00
}
2024-08-03 21:18:38 +01:00
/// A graph of `DownloadedDependencyGraphNode`s
2024-07-17 18:38:01 +01:00
pub type DownloadedGraph = Graph<DownloadedDependencyGraphNode>;
2024-08-03 21:18:38 +01:00
/// A lockfile
2024-07-12 23:09:37 +01:00
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Lockfile {
2024-08-03 21:18:38 +01:00
/// The name of the package
pub name: PackageName,
2024-08-03 21:18:38 +01:00
/// The version of the package
pub version: Version,
2024-08-03 21:18:38 +01:00
/// The target of the package
2024-07-22 22:16:04 +01:00
pub target: TargetKind,
2024-08-03 21:18:38 +01:00
/// The overrides of the package
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>,
/// The workspace members
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub workspace: BTreeMap<PackageName, BTreeMap<TargetKind, RelativePathBuf>>,
2024-08-03 21:18:38 +01:00
/// The graph of dependencies
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
2024-07-22 15:41:45 +01:00
pub graph: DownloadedGraph,
2024-07-12 23:09:37 +01:00
}