Skip to content

Commit 7d97093

Browse files
committed
differentiate wit and component deps and remove dep serde
1 parent 9e66cb2 commit 7d97093

File tree

2 files changed

+120
-180
lines changed

2 files changed

+120
-180
lines changed

crates/wasm-pkg-core/src/resolver.rs

Lines changed: 115 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ use anyhow::{bail, Context, Result};
1313
use futures_util::TryStreamExt;
1414
use indexmap::{IndexMap, IndexSet};
1515
use semver::{Comparator, Op, Version, VersionReq};
16-
use serde::{
17-
de::{self, value::MapAccessDeserializer},
18-
Deserialize, Serialize,
19-
};
2016
use tokio::io::{AsyncRead, AsyncReadExt};
2117
use wasm_pkg_client::{
2218
caching::{CachingClient, FileCache},
@@ -30,17 +26,6 @@ use crate::{lock::LockFile, wit::get_packages};
3026
/// The name of the default registry.
3127
pub const DEFAULT_REGISTRY_NAME: &str = "default";
3228

33-
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34-
pub enum DependencyKind {
35-
Component,
36-
Wit,
37-
}
38-
39-
impl Default for DependencyKind {
40-
fn default() -> Self {
41-
Self::Wit
42-
}
43-
}
4429
// TODO: functions for resolving dependencies from a lock file
4530

4631
/// Represents a WIT package dependency.
@@ -50,117 +35,7 @@ pub enum Dependency {
5035
Package(RegistryPackage),
5136

5237
/// The dependency is a path to a local directory or file.
53-
Local(PathBuf, DependencyKind),
54-
}
55-
56-
impl Serialize for Dependency {
57-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58-
where
59-
S: serde::Serializer,
60-
{
61-
match self {
62-
Self::Package(package) => {
63-
if package.name.is_none() && package.registry.is_none() {
64-
let version = package.version.to_string();
65-
version.trim_start_matches('^').serialize(serializer)
66-
} else {
67-
#[derive(Serialize)]
68-
struct Entry<'a> {
69-
package: Option<&'a PackageRef>,
70-
version: &'a str,
71-
registry: Option<&'a str>,
72-
}
73-
74-
Entry {
75-
package: package.name.as_ref(),
76-
version: package.version.to_string().trim_start_matches('^'),
77-
registry: package.registry.as_deref(),
78-
}
79-
.serialize(serializer)
80-
}
81-
}
82-
Self::Local(path, kind) => {
83-
#[derive(Serialize)]
84-
struct Entry<'a> {
85-
path: &'a PathBuf,
86-
kind: &'a DependencyKind,
87-
}
88-
89-
Entry { path, kind }.serialize(serializer)
90-
}
91-
}
92-
}
93-
}
94-
95-
impl<'de> Deserialize<'de> for Dependency {
96-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97-
where
98-
D: serde::Deserializer<'de>,
99-
{
100-
struct Visitor;
101-
102-
impl<'de> de::Visitor<'de> for Visitor {
103-
type Value = Dependency;
104-
105-
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
106-
write!(formatter, "a string or a table")
107-
}
108-
109-
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
110-
where
111-
E: de::Error,
112-
{
113-
Ok(Self::Value::Package(s.parse().map_err(de::Error::custom)?))
114-
}
115-
116-
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
117-
where
118-
A: de::MapAccess<'de>,
119-
{
120-
#[derive(Default, Deserialize)]
121-
#[serde(default, deny_unknown_fields)]
122-
struct Entry {
123-
path: Option<PathBuf>,
124-
package: Option<PackageRef>,
125-
version: Option<VersionReq>,
126-
registry: Option<String>,
127-
kind: DependencyKind,
128-
}
129-
130-
let entry = Entry::deserialize(MapAccessDeserializer::new(map))?;
131-
132-
match (
133-
entry.path,
134-
entry.package,
135-
entry.version,
136-
entry.registry,
137-
entry.kind,
138-
) {
139-
(Some(path), None, None, None, kind) => Ok(Self::Value::Local(path, kind)),
140-
(None, name, Some(version), registry, _) => {
141-
Ok(Self::Value::Package(RegistryPackage {
142-
name,
143-
version,
144-
registry,
145-
}))
146-
}
147-
(Some(_), None, Some(_), _, _) => Err(de::Error::custom(
148-
"cannot specify both `path` and `version` fields in a dependency entry",
149-
)),
150-
(Some(_), None, None, Some(_), _) => Err(de::Error::custom(
151-
"cannot specify both `path` and `registry` fields in a dependency entry",
152-
)),
153-
(Some(_), Some(_), _, _, _) => Err(de::Error::custom(
154-
"cannot specify both `path` and `package` fields in a dependency entry",
155-
)),
156-
(None, None, _, _, _) => Err(de::Error::missing_field("package")),
157-
(None, Some(_), None, _, _) => Err(de::Error::missing_field("version")),
158-
}
159-
}
160-
}
161-
162-
deserializer.deserialize_any(Visitor)
163-
}
38+
Local(PathBuf),
16439
}
16540

16641
impl FromStr for Dependency {
@@ -484,70 +359,136 @@ impl<'a> DependencyResolver<'a> {
484359

485360
/// Add a dependency to the resolver. If the dependency already exists, then it will be ignored.
486361
/// To override an existing dependency, use [`override_dependency`](Self::override_dependency).
362+
363+
#[deprecated(since = "0.9.0", note = "please use `new_method` instead")]
487364
pub async fn add_dependency(
488365
&mut self,
489366
name: &PackageRef,
490367
dependency: &Dependency,
491368
) -> Result<()> {
492-
self.add_dependency_internal(name, dependency, false).await
369+
self.add_wit_dependency_internal(name, dependency, false)
370+
.await
493371
}
494372

495-
/// Add a dependency to the resolver. If the dependency already exists, then it will be
496-
/// overridden.
497-
pub async fn override_dependency(
373+
/// Add a wit dependency to the resolver. If the dependency already exists, then it will be ignored.
374+
/// To override an existing dependency, use [`override_dependency`](Self::override_dependency).
375+
pub async fn add_wit_dependency(
376+
&mut self,
377+
name: &PackageRef,
378+
dependency: &Dependency,
379+
) -> Result<()> {
380+
self.add_wit_dependency_internal(name, dependency, false)
381+
.await
382+
}
383+
384+
/// Add a concrete component dependency to the resolver. If the dependency already exists, then it will be ignored.
385+
/// To override an existing dependency, use [`override_dependency`](Self::override_dependency).
386+
pub async fn add_component_dependency(
498387
&mut self,
499388
name: &PackageRef,
500389
dependency: &Dependency,
501390
) -> Result<()> {
502-
self.add_dependency_internal(name, dependency, true).await
391+
self.add_component_dependency_internal(name, dependency, false)
392+
.await
503393
}
504394

505-
async fn add_dependency_internal(
395+
async fn add_component_dependency_internal(
506396
&mut self,
507397
name: &PackageRef,
508398
dependency: &Dependency,
509399
force_override: bool,
510400
) -> Result<()> {
511401
match dependency {
512402
Dependency::Package(package) => {
513-
// Dependency comes from a registry, add a dependency to the resolver
514-
let registry_name = package.registry.as_deref().or_else(|| {
515-
self.client.client().ok().and_then(|client| {
516-
client
517-
.config()
518-
.resolve_registry(name)
519-
.map(|reg| reg.as_ref())
520-
})
403+
self.add_registry_package(name, force_override, package)?
404+
}
405+
Dependency::Local(p) => {
406+
// A local path dependency, insert a resolution immediately
407+
let res = DependencyResolution::Local(LocalResolution {
408+
name: name.clone(),
409+
path: p.clone(),
521410
});
522-
let package_name = package.name.clone().unwrap_or_else(|| name.clone());
523-
524-
// Resolve the version from the lock file if there is one
525-
let locked = match self.lock_file.as_ref().and_then(|resolver| {
526-
resolver
527-
.resolve(registry_name, &package_name, &package.version)
528-
.transpose()
529-
}) {
530-
Some(Ok(locked)) => Some(locked),
531-
Some(Err(e)) => return Err(e),
532-
_ => None,
533-
};
534-
535-
if !force_override
536-
&& (self.resolutions.contains_key(name) || self.dependencies.contains_key(name))
537-
{
411+
412+
if !force_override && self.resolutions.contains_key(name) {
538413
tracing::debug!(%name, "dependency already exists and override is not set, ignoring");
539414
return Ok(());
540415
}
541-
self.dependencies.insert(
542-
name.to_owned(),
543-
RegistryDependency {
544-
package: package_name,
545-
version: package.version.clone(),
546-
locked: locked.map(|l| (l.version.clone(), l.digest.clone())),
547-
},
548-
);
416+
417+
let prev = self.resolutions.insert(name.clone(), res);
418+
assert!(prev.is_none());
419+
}
420+
}
421+
422+
Ok(())
423+
}
424+
425+
/// Add a dependency to the resolver. If the dependency already exists, then it will be
426+
/// overridden.
427+
pub async fn override_dependency(
428+
&mut self,
429+
name: &PackageRef,
430+
dependency: &Dependency,
431+
) -> Result<()> {
432+
self.add_wit_dependency_internal(name, dependency, true)
433+
.await
434+
}
435+
436+
fn add_registry_package(
437+
&mut self,
438+
name: &PackageRef,
439+
force_override: bool,
440+
package: &RegistryPackage,
441+
) -> Result<()> {
442+
// Dependency comes from a registry, add a dependency to the resolver
443+
let registry_name = package.registry.as_deref().or_else(|| {
444+
self.client.client().ok().and_then(|client| {
445+
client
446+
.config()
447+
.resolve_registry(name)
448+
.map(|reg| reg.as_ref())
449+
})
450+
});
451+
let package_name = package.name.clone().unwrap_or_else(|| name.clone());
452+
453+
// Resolve the version from the lock file if there is one
454+
let locked = match self.lock_file.as_ref().and_then(|resolver| {
455+
resolver
456+
.resolve(registry_name, &package_name, &package.version)
457+
.transpose()
458+
}) {
459+
Some(Ok(locked)) => Some(locked),
460+
Some(Err(e)) => return Err(e),
461+
_ => None,
462+
};
463+
464+
if !force_override
465+
&& (self.resolutions.contains_key(name) || self.dependencies.contains_key(name))
466+
{
467+
tracing::debug!(%name, "dependency already exists and override is not set, ignoring");
468+
return Ok(());
469+
}
470+
self.dependencies.insert(
471+
name.to_owned(),
472+
RegistryDependency {
473+
package: package_name,
474+
version: package.version.clone(),
475+
locked: locked.map(|l| (l.version.clone(), l.digest.clone())),
476+
},
477+
);
478+
Ok(())
479+
}
480+
481+
async fn add_wit_dependency_internal(
482+
&mut self,
483+
name: &PackageRef,
484+
dependency: &Dependency,
485+
force_override: bool,
486+
) -> Result<()> {
487+
match dependency {
488+
Dependency::Package(package) => {
489+
self.add_registry_package(name, force_override, package)?
549490
}
550-
Dependency::Local(p, kind) => {
491+
Dependency::Local(p) => {
551492
// A local path dependency, insert a resolution immediately
552493
let res = DependencyResolution::Local(LocalResolution {
553494
name: name.clone(),
@@ -562,13 +503,11 @@ impl<'a> DependencyResolver<'a> {
562503
// // Now that we check we haven't already inserted this dep, get the packages from the
563504
// // local dependency and add those to the resolver before adding the dependency
564505
// if is_wit {
565-
if kind == &DependencyKind::Wit {
566-
let (_, packages) = get_packages(p)
567-
.context("Error getting dependent packages from local dependency")?;
568-
Box::pin(self.add_packages(packages))
569-
.await
570-
.context("Error adding packages to resolver for local dependency")?;
571-
}
506+
let (_, packages) = get_packages(p)
507+
.context("Error getting dependent packages from local dependency")?;
508+
Box::pin(self.add_packages(packages))
509+
.await
510+
.context("Error adding packages to resolver for local dependency")?;
572511
// }
573512

574513
let prev = self.resolutions.insert(name.clone(), res);
@@ -586,7 +525,7 @@ impl<'a> DependencyResolver<'a> {
586525
packages: impl IntoIterator<Item = (PackageRef, VersionReq)>,
587526
) -> Result<()> {
588527
for (package, req) in packages {
589-
self.add_dependency(
528+
self.add_wit_dependency(
590529
&package,
591530
&Dependency::Package(RegistryPackage {
592531
name: Some(package.clone()),
@@ -717,10 +656,11 @@ fn find_latest_release<'a>(
717656
versions: &'a [VersionInfo],
718657
req: &VersionReq,
719658
) -> Option<&'a VersionInfo> {
720-
versions
659+
let versions = versions
721660
.iter()
722661
.filter(|info| !info.yanked && req.matches(&info.version))
723-
.max_by(|a, b| a.version.cmp(&b.version))
662+
.max_by(|a, b| a.version.cmp(&b.version));
663+
versions
724664
}
725665

726666
// NOTE(thomastaylor312): This is copied from the old wit package in the cargo-component and broken

0 commit comments

Comments
 (0)