mirror of
https://github.com/pesde-pkg/pesde.git
synced 2024-12-12 11:00:36 +00:00
feat: implement multi target packages
This commit is contained in:
parent
14463b7205
commit
2898b02e1c
10 changed files with 148 additions and 117 deletions
|
@ -63,6 +63,7 @@ impl InstallCommand {
|
|||
.write_lockfile(Lockfile {
|
||||
name: manifest.name,
|
||||
version: manifest.version,
|
||||
target: manifest.target.kind(),
|
||||
overrides: manifest.overrides,
|
||||
|
||||
graph: downloaded_graph,
|
||||
|
|
|
@ -245,9 +245,16 @@ impl IsUpToDate for Project {
|
|||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
|
||||
if manifest.overrides != lockfile.overrides {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if manifest.target.kind() != lockfile.target {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if !strict {
|
||||
// the resolver will use the old lockfile and update it itself. it can't handle overrides only
|
||||
return Ok(manifest.overrides == lockfile.overrides);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if manifest.name != lockfile.name || manifest.version != lockfile.version {
|
||||
|
|
|
@ -30,7 +30,7 @@ impl RunCommand {
|
|||
|
||||
let pkg_name = PackageNames::Pesde(pkg_name);
|
||||
|
||||
for (version, node) in graph.get(&pkg_name).context("package not found in graph")? {
|
||||
for (version_id, node) in graph.get(&pkg_name).context("package not found in graph")? {
|
||||
if node.node.direct.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl RunCommand {
|
|||
.join(base_folder)
|
||||
.join(PACKAGES_CONTAINER_NAME),
|
||||
&pkg_name,
|
||||
version,
|
||||
version_id.version(),
|
||||
);
|
||||
|
||||
let path = bin_path.to_path(&container_folder);
|
||||
|
|
|
@ -21,7 +21,7 @@ impl Project {
|
|||
let mut downloaded_graph: DownloadedGraph = BTreeMap::new();
|
||||
|
||||
for (name, versions) in graph {
|
||||
for (version, node) in versions {
|
||||
for (version_id, node) in versions {
|
||||
let source = match &node.pkg_ref {
|
||||
PackageRefs::Pesde(pkg_ref) => {
|
||||
PackageSources::Pesde(PesdePackageSource::new(pkg_ref.index_url.clone()))
|
||||
|
@ -38,7 +38,7 @@ impl Project {
|
|||
.join(node.base_folder(manifest.target.kind(), true))
|
||||
.join(PACKAGES_CONTAINER_NAME),
|
||||
name,
|
||||
version,
|
||||
version_id.version(),
|
||||
);
|
||||
|
||||
create_dir_all(&container_folder)?;
|
||||
|
@ -46,7 +46,7 @@ impl Project {
|
|||
let target = source.download(&node.pkg_ref, &container_folder, self)?;
|
||||
|
||||
downloaded_graph.entry(name.clone()).or_default().insert(
|
||||
version.clone(),
|
||||
version_id.clone(),
|
||||
DownloadedDependencyGraphNode {
|
||||
node: node.clone(),
|
||||
target,
|
||||
|
|
|
@ -4,10 +4,9 @@ use crate::{
|
|||
manifest::{ScriptName, Target},
|
||||
names::PackageNames,
|
||||
scripts::execute_script,
|
||||
source::PackageRef,
|
||||
source::{PackageRef, VersionId},
|
||||
Project, PACKAGES_CONTAINER_NAME,
|
||||
};
|
||||
use semver::Version;
|
||||
use std::{collections::BTreeMap, fs::create_dir_all};
|
||||
|
||||
pub mod generator;
|
||||
|
@ -16,10 +15,10 @@ impl Project {
|
|||
pub fn link_dependencies(&self, graph: &DownloadedGraph) -> Result<(), errors::LinkingError> {
|
||||
let manifest = self.deser_manifest()?;
|
||||
|
||||
let mut package_types = BTreeMap::<&PackageNames, BTreeMap<&Version, Vec<String>>>::new();
|
||||
let mut package_types = BTreeMap::<&PackageNames, BTreeMap<&VersionId, Vec<String>>>::new();
|
||||
|
||||
for (name, versions) in graph {
|
||||
for (version, node) in versions {
|
||||
for (version_id, node) in versions {
|
||||
let Some(lib_file) = node.target.lib_path() else {
|
||||
continue;
|
||||
};
|
||||
|
@ -30,7 +29,7 @@ impl Project {
|
|||
.join(node.node.base_folder(manifest.target.kind(), true))
|
||||
.join(PACKAGES_CONTAINER_NAME),
|
||||
name,
|
||||
version,
|
||||
version_id.version(),
|
||||
);
|
||||
|
||||
let lib_file = lib_file.to_path(&container_folder);
|
||||
|
@ -58,7 +57,7 @@ impl Project {
|
|||
package_types
|
||||
.entry(name)
|
||||
.or_default()
|
||||
.insert(version, types);
|
||||
.insert(version_id, types);
|
||||
|
||||
#[cfg(feature = "roblox")]
|
||||
if let Target::Roblox { build_files, .. } = &node.target {
|
||||
|
@ -87,7 +86,7 @@ impl Project {
|
|||
}
|
||||
|
||||
for (name, versions) in graph {
|
||||
for (version, node) in versions {
|
||||
for (version_id, node) in versions {
|
||||
let base_folder = self.path().join(
|
||||
self.path()
|
||||
.join(node.node.base_folder(manifest.target.kind(), true)),
|
||||
|
@ -96,13 +95,15 @@ impl Project {
|
|||
let base_folder = base_folder.canonicalize()?;
|
||||
let packages_container_folder = base_folder.join(PACKAGES_CONTAINER_NAME);
|
||||
|
||||
let container_folder =
|
||||
node.node
|
||||
.container_folder(&packages_container_folder, name, version);
|
||||
let container_folder = node.node.container_folder(
|
||||
&packages_container_folder,
|
||||
name,
|
||||
version_id.version(),
|
||||
);
|
||||
|
||||
if let Some((alias, types)) = package_types
|
||||
.get(name)
|
||||
.and_then(|v| v.get(version))
|
||||
.and_then(|v| v.get(version_id))
|
||||
.and_then(|types| node.node.direct.as_ref().map(|(alias, _)| (alias, types)))
|
||||
{
|
||||
let module = generator::generate_linking_module(
|
||||
|
@ -118,23 +119,23 @@ impl Project {
|
|||
std::fs::write(base_folder.join(format!("{alias}.luau")), module)?;
|
||||
}
|
||||
|
||||
for (dependency_name, (dependency_version, dependency_alias)) in
|
||||
for (dependency_name, (dependency_version_id, dependency_alias)) in
|
||||
&node.node.dependencies
|
||||
{
|
||||
let Some(dependency_node) = graph
|
||||
.get(dependency_name)
|
||||
.and_then(|v| v.get(dependency_version))
|
||||
.and_then(|v| v.get(dependency_version_id))
|
||||
else {
|
||||
return Err(errors::LinkingError::DependencyNotFound(
|
||||
dependency_name.to_string(),
|
||||
dependency_version.to_string(),
|
||||
dependency_version_id.to_string(),
|
||||
));
|
||||
};
|
||||
|
||||
let dependency_container_folder = dependency_node.node.container_folder(
|
||||
&packages_container_folder,
|
||||
dependency_name,
|
||||
dependency_version,
|
||||
dependency_version_id.version(),
|
||||
);
|
||||
|
||||
let linker_folder = container_folder
|
||||
|
@ -153,7 +154,7 @@ impl Project {
|
|||
)?,
|
||||
package_types
|
||||
.get(dependency_name)
|
||||
.and_then(|v| v.get(dependency_version))
|
||||
.and_then(|v| v.get(dependency_version_id))
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
manifest::{DependencyType, OverrideKey, Target, TargetKind},
|
||||
names::{PackageName, PackageNames},
|
||||
source::{DependencySpecifiers, PackageRef, PackageRefs},
|
||||
source::{DependencySpecifiers, PackageRef, PackageRefs, VersionId},
|
||||
};
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -10,16 +10,16 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
pub type Graph<Node> = BTreeMap<PackageNames, BTreeMap<Version, Node>>;
|
||||
pub type Graph<Node> = BTreeMap<PackageNames, BTreeMap<VersionId, Node>>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct DependencyGraphNode {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub direct: Option<(String, DependencySpecifiers)>,
|
||||
pub pkg_ref: PackageRefs,
|
||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||
pub dependencies: BTreeMap<PackageNames, (Version, String)>,
|
||||
pub dependencies: BTreeMap<PackageNames, (VersionId, String)>,
|
||||
pub ty: DependencyType,
|
||||
pub pkg_ref: PackageRefs,
|
||||
}
|
||||
|
||||
impl DependencyGraphNode {
|
||||
|
@ -49,7 +49,7 @@ pub type DependencyGraph = Graph<DependencyGraphNode>;
|
|||
pub fn insert_node(
|
||||
graph: &mut DependencyGraph,
|
||||
name: PackageNames,
|
||||
version: Version,
|
||||
version: VersionId,
|
||||
mut node: DependencyGraphNode,
|
||||
is_top_level: bool,
|
||||
) {
|
||||
|
@ -85,8 +85,9 @@ pub fn insert_node(
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct DownloadedDependencyGraphNode {
|
||||
pub node: DependencyGraphNode,
|
||||
pub target: Target,
|
||||
#[serde(flatten)]
|
||||
pub node: DependencyGraphNode,
|
||||
}
|
||||
|
||||
pub type DownloadedGraph = Graph<DownloadedDependencyGraphNode>;
|
||||
|
@ -95,6 +96,7 @@ pub type DownloadedGraph = Graph<DownloadedDependencyGraphNode>;
|
|||
pub struct Lockfile {
|
||||
pub name: PackageName,
|
||||
pub version: Version,
|
||||
pub target: TargetKind,
|
||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||
pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>,
|
||||
|
||||
|
|
|
@ -4,14 +4,13 @@ use crate::{
|
|||
names::PackageNames,
|
||||
source::{
|
||||
pesde::PesdePackageSource, DependencySpecifiers, PackageRef, PackageSource, PackageSources,
|
||||
VersionId,
|
||||
},
|
||||
Project, DEFAULT_INDEX_NAME,
|
||||
};
|
||||
use semver::Version;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
impl Project {
|
||||
// TODO: account for targets using the is_compatible_with method
|
||||
pub fn dependency_graph(
|
||||
&self,
|
||||
previous_graph: Option<&DependencyGraph>,
|
||||
|
@ -106,14 +105,17 @@ impl Project {
|
|||
alias.to_string(),
|
||||
spec,
|
||||
ty,
|
||||
None::<(PackageNames, Version)>,
|
||||
None::<(PackageNames, VersionId)>,
|
||||
vec![alias.to_string()],
|
||||
false,
|
||||
manifest.target.kind(),
|
||||
)
|
||||
})
|
||||
.collect::<VecDeque<_>>();
|
||||
|
||||
while let Some((alias, specifier, ty, dependant, path, overridden)) = queue.pop_front() {
|
||||
while let Some((alias, specifier, ty, dependant, path, overridden, target)) =
|
||||
queue.pop_front()
|
||||
{
|
||||
let depth = path.len() - 1;
|
||||
|
||||
log::debug!(
|
||||
|
@ -155,10 +157,10 @@ impl Project {
|
|||
}
|
||||
|
||||
let (name, resolved) = source
|
||||
.resolve(&specifier, self)
|
||||
.resolve(&specifier, self, target)
|
||||
.map_err(|e| Box::new(e.into()))?;
|
||||
|
||||
let Some(target_version) = graph
|
||||
let Some(target_version_id) = graph
|
||||
.get(&name)
|
||||
.and_then(|versions| {
|
||||
versions
|
||||
|
@ -170,11 +172,9 @@ impl Project {
|
|||
.or_else(|| resolved.last_key_value().map(|(ver, _)| ver))
|
||||
.cloned()
|
||||
else {
|
||||
log::warn!(
|
||||
"{}could not find any version for {specifier} ({alias})",
|
||||
"\t".repeat(depth)
|
||||
);
|
||||
continue;
|
||||
return Err(Box::new(errors::DependencyGraphError::NoMatchingVersion(
|
||||
format!("{specifier} ({})", manifest.target.kind()),
|
||||
)));
|
||||
};
|
||||
|
||||
let ty = if depth == 0 && ty == DependencyType::Peer {
|
||||
|
@ -183,25 +183,25 @@ impl Project {
|
|||
ty
|
||||
};
|
||||
|
||||
if let Some((dependant_name, dependant_version)) = dependant {
|
||||
if let Some((dependant_name, dependant_version_id)) = dependant {
|
||||
graph
|
||||
.get_mut(&dependant_name)
|
||||
.and_then(|versions| versions.get_mut(&dependant_version))
|
||||
.and_then(|versions| versions.get_mut(&dependant_version_id))
|
||||
.and_then(|node| {
|
||||
node.dependencies
|
||||
.insert(name.clone(), (target_version.clone(), alias.clone()))
|
||||
.insert(name.clone(), (target_version_id.clone(), alias.clone()))
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(already_resolved) = graph
|
||||
.get_mut(&name)
|
||||
.and_then(|versions| versions.get_mut(&target_version))
|
||||
.and_then(|versions| versions.get_mut(&target_version_id))
|
||||
{
|
||||
log::debug!(
|
||||
"{}{}@{} already resolved",
|
||||
"\t".repeat(depth),
|
||||
name,
|
||||
target_version
|
||||
target_version_id
|
||||
);
|
||||
|
||||
if already_resolved.ty == DependencyType::Peer && ty == DependencyType::Standard {
|
||||
|
@ -211,7 +211,7 @@ impl Project {
|
|||
continue;
|
||||
}
|
||||
|
||||
let pkg_ref = &resolved[&target_version];
|
||||
let pkg_ref = &resolved[&target_version_id];
|
||||
let node = DependencyGraphNode {
|
||||
direct: if depth == 0 {
|
||||
Some((alias.clone(), specifier.clone()))
|
||||
|
@ -225,7 +225,7 @@ impl Project {
|
|||
insert_node(
|
||||
&mut graph,
|
||||
name.clone(),
|
||||
target_version.clone(),
|
||||
target_version_id.clone(),
|
||||
node.clone(),
|
||||
depth == 0,
|
||||
);
|
||||
|
@ -234,7 +234,7 @@ impl Project {
|
|||
"{}resolved {}@{} from new dependency graph",
|
||||
"\t".repeat(depth),
|
||||
name,
|
||||
target_version
|
||||
target_version_id
|
||||
);
|
||||
|
||||
for (dependency_alias, (dependency_spec, dependency_ty)) in
|
||||
|
@ -262,20 +262,21 @@ impl Project {
|
|||
dependency_alias,
|
||||
overridden.cloned().unwrap_or(dependency_spec),
|
||||
dependency_ty,
|
||||
Some((name.clone(), target_version.clone())),
|
||||
Some((name.clone(), target_version_id.clone())),
|
||||
path.iter()
|
||||
.cloned()
|
||||
.chain(std::iter::once(alias.to_string()))
|
||||
.collect(),
|
||||
overridden.is_some(),
|
||||
pkg_ref.target_kind(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
for (name, versions) in &graph {
|
||||
for (version, node) in versions {
|
||||
for (version_id, node) in versions {
|
||||
if node.ty == DependencyType::Peer {
|
||||
log::warn!("peer dependency {name}@{version} was not resolved");
|
||||
log::warn!("peer dependency {name}@{version_id} was not resolved");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,5 +311,8 @@ pub mod errors {
|
|||
|
||||
#[error("error resolving package")]
|
||||
Resolve(#[from] crate::source::errors::ResolveError),
|
||||
|
||||
#[error("no matching version found for {0}")]
|
||||
NoMatchingVersion(String),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use std::{
|
||||
collections::BTreeMap,
|
||||
fmt::{Debug, Display},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
manifest::{DependencyType, Target, TargetKind},
|
||||
names::PackageNames,
|
||||
Project,
|
||||
};
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fmt::{Debug, Display},
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
pub mod pesde;
|
||||
|
||||
|
@ -40,6 +40,7 @@ impl Display for DependencySpecifiers {
|
|||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "snake_case", tag = "ref_ty")]
|
||||
pub enum PackageRefs {
|
||||
Pesde(pesde::pkg_ref::PesdePackageRef),
|
||||
}
|
||||
|
@ -68,7 +69,43 @@ impl PackageRef for PackageRefs {
|
|||
}
|
||||
}
|
||||
|
||||
pub type ResolveResult<Ref> = (PackageNames, BTreeMap<Version, Ref>);
|
||||
#[derive(
|
||||
Debug, SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
|
||||
)]
|
||||
pub struct VersionId(Version, TargetKind);
|
||||
|
||||
impl VersionId {
|
||||
pub fn version(&self) -> &Version {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn target(&self) -> &TargetKind {
|
||||
&self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for VersionId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} {}", self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for VersionId {
|
||||
type Err = errors::VersionIdParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let Some((version, target)) = s.split_once(' ') else {
|
||||
return Err(errors::VersionIdParseError::Malformed(s.to_string()));
|
||||
};
|
||||
|
||||
let version = version.parse()?;
|
||||
let target = target.parse()?;
|
||||
|
||||
Ok(VersionId(version, target))
|
||||
}
|
||||
}
|
||||
|
||||
pub type ResolveResult<Ref> = (PackageNames, BTreeMap<VersionId, Ref>);
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||
pub enum PackageSources {
|
||||
|
@ -89,6 +126,7 @@ pub trait PackageSource: Debug {
|
|||
&self,
|
||||
specifier: &Self::Specifier,
|
||||
project: &Project,
|
||||
project_target: TargetKind,
|
||||
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError>;
|
||||
|
||||
fn download(
|
||||
|
@ -115,10 +153,11 @@ impl PackageSource for PackageSources {
|
|||
&self,
|
||||
specifier: &Self::Specifier,
|
||||
project: &Project,
|
||||
project_target: TargetKind,
|
||||
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> {
|
||||
match (self, specifier) {
|
||||
(PackageSources::Pesde(source), DependencySpecifiers::Pesde(specifier)) => source
|
||||
.resolve(specifier, project)
|
||||
.resolve(specifier, project, project_target)
|
||||
.map(|(name, results)| {
|
||||
(
|
||||
name,
|
||||
|
@ -179,4 +218,17 @@ pub mod errors {
|
|||
#[error("error downloading pesde package")]
|
||||
Pesde(#[from] crate::source::pesde::errors::DownloadError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum VersionIdParseError {
|
||||
#[error("malformed entry key {0}")]
|
||||
Malformed(String),
|
||||
|
||||
#[error("malformed version")]
|
||||
Version(#[from] semver::Error),
|
||||
|
||||
#[error("malformed target")]
|
||||
Target(#[from] crate::manifest::errors::TargetKindFromStr),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
use std::{
|
||||
collections::BTreeMap,
|
||||
fmt::{Debug, Display},
|
||||
hash::Hash,
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
use std::{collections::BTreeMap, fmt::Debug, hash::Hash, path::Path};
|
||||
|
||||
use gix::remote::Direction;
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
|
||||
use pkg_ref::PesdePackageRef;
|
||||
use specifier::PesdeDependencySpecifier;
|
||||
|
||||
use crate::manifest::TargetKind;
|
||||
use crate::{
|
||||
manifest::{DependencyType, Target, TargetKind},
|
||||
manifest::{DependencyType, Target},
|
||||
names::{PackageName, PackageNames},
|
||||
source::{hash, DependencySpecifiers, PackageSource, ResolveResult},
|
||||
source::{hash, DependencySpecifiers, PackageSource, ResolveResult, VersionId},
|
||||
util::authenticate_conn,
|
||||
Project, REQWEST_CLIENT,
|
||||
};
|
||||
|
@ -307,6 +300,7 @@ impl PackageSource for PesdePackageSource {
|
|||
&self,
|
||||
specifier: &Self::Specifier,
|
||||
project: &Project,
|
||||
project_target: TargetKind,
|
||||
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> {
|
||||
let (scope, name) = specifier.name.as_str();
|
||||
let string = match self.read_file([scope, name], project) {
|
||||
|
@ -322,10 +316,17 @@ impl PackageSource for PesdePackageSource {
|
|||
PackageNames::Pesde(specifier.name.clone()),
|
||||
entries
|
||||
.into_iter()
|
||||
.filter(|(EntryKey(version, _), _)| specifier.version.matches(version))
|
||||
.map(|(EntryKey(version, _), entry)| {
|
||||
.filter(|(VersionId(version, target), _)| {
|
||||
specifier.version.matches(version)
|
||||
&& specifier
|
||||
.target
|
||||
.map_or(project_target.is_compatible_with(target), |t| t == *target)
|
||||
})
|
||||
.map(|(id, entry)| {
|
||||
let version = id.version().clone();
|
||||
|
||||
(
|
||||
version.clone(),
|
||||
id,
|
||||
PesdePackageRef {
|
||||
name: specifier.name.clone(),
|
||||
version,
|
||||
|
@ -413,33 +414,7 @@ pub struct IndexFileEntry {
|
|||
pub dependencies: BTreeMap<String, (DependencySpecifiers, DependencyType)>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
|
||||
)]
|
||||
pub struct EntryKey(pub Version, pub TargetKind);
|
||||
|
||||
impl Display for EntryKey {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} {}", self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for EntryKey {
|
||||
type Err = errors::EntryKeyParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let Some((version, target)) = s.split_once(' ') else {
|
||||
return Err(errors::EntryKeyParseError::Malformed(s.to_string()));
|
||||
};
|
||||
|
||||
let version = version.parse()?;
|
||||
let target = target.parse()?;
|
||||
|
||||
Ok(EntryKey(version, target))
|
||||
}
|
||||
}
|
||||
|
||||
pub type IndexFile = BTreeMap<EntryKey, IndexFileEntry>;
|
||||
pub type IndexFile = BTreeMap<VersionId, IndexFileEntry>;
|
||||
|
||||
pub mod errors {
|
||||
use std::path::PathBuf;
|
||||
|
@ -593,17 +568,4 @@ pub mod errors {
|
|||
#[error("error unpacking package")]
|
||||
Unpack(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum EntryKeyParseError {
|
||||
#[error("malformed entry key {0}")]
|
||||
Malformed(String),
|
||||
|
||||
#[error("malformed version")]
|
||||
Version(#[from] semver::Error),
|
||||
|
||||
#[error("malformed target")]
|
||||
Target(#[from] crate::manifest::errors::TargetKindFromStr),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{names::PackageName, source::DependencySpecifier};
|
||||
use crate::{manifest::TargetKind, names::PackageName, source::DependencySpecifier};
|
||||
use semver::VersionReq;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Display;
|
||||
|
@ -9,6 +9,8 @@ pub struct PesdeDependencySpecifier {
|
|||
pub version: VersionReq,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub index: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub target: Option<TargetKind>,
|
||||
}
|
||||
impl DependencySpecifier for PesdeDependencySpecifier {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue