Skip to content

Commit bc8db16

Browse files
committed
added take_ready test case
1 parent 42c9cbd commit bc8db16

6 files changed

Lines changed: 99 additions & 69 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/wasm-pkg-common/src/package.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ impl PackageSpec {
9595
}
9696
}
9797

98+
impl PartialEq<str> for PackageSpec {
99+
fn eq(&self, other: &str) -> bool {
100+
&format!("{self}") == other
101+
}
102+
}
103+
98104
impl FromStr for PackageSpec {
99105
type Err = Error;
100106

crates/wasm-pkg-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ features = [
4343
tempfile = { workspace = true }
4444
sha2 = { workspace = true }
4545
rstest = "0.23"
46+
glob = "0.3.3"

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

Lines changed: 83 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -885,12 +885,20 @@ impl PublishPlan {
885885

886886
if neighbors.peek().is_none() {
887887
// tracing::debug!("{dep} has no dependents");
888-
println!("{dep} has no dependents");
888+
println!("[{dep} has no dependents]");
889+
} else {
890+
println!("[{dep}]");
889891
}
890892

891893
while let Some(id) = neighbors.next() {
892894
let pkg = &self.dependents[id];
893-
println!("{dep} -(DependencyOF)-> {pkg}");
895+
let separator = if neighbors.peek().is_some() {
896+
"├─"
897+
} else {
898+
"╰─"
899+
};
900+
901+
println!("{separator}(DependencyOf)─▶ {pkg}");
894902
}
895903

896904
dep
@@ -912,12 +920,13 @@ impl PublishPlan {
912920
self.dependents
913921
.nodes_iter()
914922
// there are no dependents on `self.dendents[id]`
915-
.filter(|id| self.dependents.neighbors(*id).count() == 0)
916-
.map(|id| {
917-
let pkg = &self.dependents[id];
918-
self.indices.remove(&pkg.package);
919-
pkg.clone()
923+
.filter(|id| {
924+
self.dependents
925+
.neighbors_directed(*id, Direction::Incoming)
926+
.count()
927+
== 0
920928
})
929+
.map(|id| self.dependents[id].clone())
921930
.collect()
922931
}
923932

@@ -928,15 +937,37 @@ impl PublishPlan {
928937

929938
/// Packages confirmed to be available in the registry, potentially allowing additional
930939
/// packages to be "ready".
931-
pub fn mark_confirmed(&mut self, published: impl IntoIterator<Item = PackageRef>) {
932-
for pkg in published {
940+
pub fn mark_confirmed(&mut self, published: impl IntoIterator<Item = PackageSpec>) {
941+
for spec in published {
933942
let (id, _) = self
934943
.indices
935-
.remove(&pkg)
944+
.remove(&spec.package)
936945
.expect("PackageSpec has no associated index");
937-
self.dependents
938-
.remove_node(id)
939-
.expect("index has no associated PackageSpec");
946+
// NOTE: nodes without edges will return None here
947+
self.dependents.remove_node(id);
948+
}
949+
}
950+
}
951+
952+
/// Format a collection of packages as a list
953+
///
954+
/// e.g. "foo:a@0.1.0, bar:b@0.2.0, and baz:c@0.3.0".
955+
///
956+
/// Note: the final separator (e.g. "and" in the previous example) can be chosen.
957+
pub fn package_list<'a>(
958+
pkgs: impl IntoIterator<Item = &'a PackageSpec>,
959+
final_sep: Option<&str>,
960+
) -> String {
961+
let final_sep = final_sep.unwrap_or("and");
962+
let mut names: Vec<_> = pkgs.into_iter().map(|pkg| pkg.to_string()).collect();
963+
names.sort();
964+
965+
match &names[..] {
966+
[] => String::new(),
967+
[a] => a.clone(),
968+
[a, b] => format!("{a} {final_sep} {b}"),
969+
[names @ .., last] => {
970+
format!("{}, {final_sep} {last}", names.join(", "))
940971
}
941972
}
942973
}
@@ -946,69 +977,57 @@ mod tests {
946977
use std::collections::HashSet;
947978
use std::path::PathBuf;
948979

949-
use super::PublishPlan;
980+
use super::*;
981+
use glob::glob;
950982
use wasm_pkg_client::PackageRef;
951983

952984
fn transitive_local_paths() -> Vec<PathBuf> {
953-
let fixtures =
954-
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/transitive-local");
955-
["example-a", "example-b", "example-c"]
985+
let fixtures = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
986+
.join("tests/fixtures/transitive-local/*/wit/");
987+
glob(fixtures.to_str().unwrap())
988+
.unwrap()
956989
.into_iter()
957-
.map(|name| fixtures.join(name).join("wit"))
990+
.map(|p| p.expect("glob path error"))
958991
.collect()
959992
}
960993

961994
#[test]
962-
fn publish_plan_from_paths_collects_all_packages() {
995+
fn publish_plan_iter() {
963996
let paths = transitive_local_paths();
964-
let plan = PublishPlan::from_paths(&paths).expect("plan should build");
965-
966-
assert!(!plan.is_empty());
967-
assert_eq!(plan.len(), 3);
968-
969-
for name in ["example-a:foo", "example-b:bar", "example-c:baz"] {
970-
let pkg: PackageRef = name.parse().expect("valid package ref");
971-
assert!(
972-
plan.get_path(&pkg).is_some(),
973-
"expected `{name}` to have an associated path in the plan",
974-
);
975-
}
997+
let plan = PublishPlan::from_paths(&paths).unwrap();
998+
assert_eq!(
999+
plan.iter().count(),
1000+
4,
1001+
"unexpected package count\npackages found: {}",
1002+
package_list(plan.iter(), None)
1003+
);
9761004
}
9771005

9781006
#[test]
979-
fn publish_plan_iter_yields_each_package_once() {
1007+
fn publish_plan_chunks() {
9801008
let paths = transitive_local_paths();
981-
let plan = PublishPlan::from_paths(&paths).expect("plan should build");
982-
983-
let seen: Vec<PackageRef> = plan.iter().map(|spec| spec.package.clone()).collect();
984-
assert_eq!(seen.len(), 3, "iter should yield one entry per package");
985-
986-
let unique: HashSet<_> = seen.iter().cloned().collect();
987-
assert_eq!(unique.len(), seen.len(), "iter must not yield duplicates");
988-
989-
let expected: HashSet<PackageRef> = ["example-a:foo", "example-b:bar", "example-c:baz"]
990-
.into_iter()
991-
.map(|s| s.parse().unwrap())
992-
.collect();
993-
assert_eq!(unique, expected);
994-
}
995-
}
996-
997-
/// Format a collection of packages as a list
998-
///
999-
/// e.g. "foo:a@0.1.0, bar:b@0.2.0, and baz:c@0.3.0".
1000-
///
1001-
/// Note: the final separator (e.g. "and" in the previous example) can be chosen.
1002-
pub fn package_list(pkgs: impl IntoIterator<Item = PackageSpec>, final_sep: &str) -> String {
1003-
let mut names: Vec<_> = pkgs.into_iter().map(|pkg| pkg.to_string()).collect();
1004-
names.sort();
1005-
1006-
match &names[..] {
1007-
[] => String::new(),
1008-
[a] => a.clone(),
1009-
[a, b] => format!("{a} {final_sep} {b}"),
1010-
[names @ .., last] => {
1011-
format!("{}, {final_sep} {last}", names.join(", "))
1012-
}
1009+
let mut plan = PublishPlan::from_paths(&paths).unwrap();
1010+
let mut ready_for_publish = plan.take_ready();
1011+
assert_eq!(
1012+
ready_for_publish.iter().collect::<Vec<_>>(),
1013+
["example-c:baz@0.1.0", "example-d:foo@0.1.0"],
1014+
);
1015+
plan.mark_confirmed(ready_for_publish.into_iter());
1016+
1017+
ready_for_publish = plan.take_ready();
1018+
assert_eq!(
1019+
ready_for_publish.iter().collect::<Vec<_>>(),
1020+
["example-b:bar@0.1.0"],
1021+
);
1022+
plan.mark_confirmed(ready_for_publish.into_iter());
1023+
1024+
ready_for_publish = plan.take_ready();
1025+
assert_eq!(
1026+
ready_for_publish.iter().collect::<Vec<_>>(),
1027+
["example-a:foo@0.1.0"],
1028+
);
1029+
plan.mark_confirmed(ready_for_publish.into_iter());
1030+
1031+
assert!(plan.is_empty());
10131032
}
10141033
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,12 @@ pub fn get_local_dependencies(
204204
for (dep, _version) in deps {
205205
if let Some(&(dep, _)) = indices.get(&dep) {
206206
let (pkg, _) = indices[&spec.package];
207-
// // dep -(DependencyOF)-> pkg
208-
// graph.try_update_edge(dep, pkg, Direction::Outgoing);
209-
// // pkg -(DependsOn)-> dep
207+
// // pkg <=DependsOn= dep
210208
graph
211-
.try_update_edge(pkg, dep, Direction::Outgoing)
209+
.try_update_edge(pkg, dep, Direction::Incoming)
212210
.map_err(|e| match e {
213211
petgraph::acyclic::AcyclicEdgeError::Cycle(cycle) => {
214-
anyhow::anyhow!("cyclical depndency detected")
212+
anyhow::anyhow!("cyclical dependency detected")
215213
.context(format!("package {}", graph[cycle.node_id()]))
216214
.context(format!("package {}", graph[pkg]))
217215
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package example-d:foo@0.1.0;
2+
3+
interface bar {
4+
type baz = string;
5+
}

0 commit comments

Comments
 (0)