Skip to content

Commit 888f6da

Browse files
authored
[packages] Fix dependency override prunning issue (#13921)
## Description Fixes an issue related to pruning overridden dependencies during dependency graph construction. More concretely, when tryin to find dependency paths in a pruned sub-graph, one could encounter no target node if this node was representing a pruned overridden package. The proposed solution is to simply also search for the target node in the overrides map (if a search for it in the sub-graph fails) ## Test Plan Added a test for this specific scenario, plus all existing tests must pass. --- If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process. ### Type of Change (Check all that apply) - [ ] protocol change - [ ] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes
1 parent 7d8f830 commit 888f6da

File tree

8 files changed

+408
-18
lines changed

8 files changed

+408
-18
lines changed

tools/move-package/src/resolution/dependency_graph.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl<Progress: Write> DependencyGraphBuilder<Progress> {
270270
.add_node(combined_graph.root_package);
271271

272272
// get overrides
273-
let overrides = collect_overrides(parent, &root_manifest.dependencies)?;
273+
let mut overrides = collect_overrides(parent, &root_manifest.dependencies)?;
274274
let dev_overrides = collect_overrides(parent, &root_manifest.dev_dependencies)?;
275275

276276
for (
@@ -296,7 +296,10 @@ impl<Progress: Write> DependencyGraphBuilder<Progress> {
296296
let mut all_deps = root_manifest.dependencies.clone();
297297
all_deps.extend(root_manifest.dev_dependencies.clone());
298298

299-
combined_graph.merge(dep_graphs, parent, &all_deps)?;
299+
// we can mash overrides together as the sets cannot overlap (it's asserted during pruning)
300+
overrides.extend(dev_overrides);
301+
302+
combined_graph.merge(dep_graphs, parent, &all_deps, &overrides)?;
300303

301304
combined_graph.check_acyclic()?;
302305
combined_graph.discover_always_deps();
@@ -563,6 +566,7 @@ impl DependencyGraph {
563566
mut dep_graphs: BTreeMap<PM::PackageName, DependencyGraphInfo>,
564567
parent: &PM::DependencyKind,
565568
dependencies: &PM::Dependencies,
569+
overrides: &BTreeMap<PM::PackageName, Package>,
566570
) -> Result<()> {
567571
if !self.always_deps.is_empty() {
568572
bail!("Merging dependencies into a graph after calculating its 'always' dependencies");
@@ -664,6 +668,7 @@ impl DependencyGraph {
664668
&dep_graphs,
665669
graph_info.is_external,
666670
),
671+
overrides,
667672
) {
668673
Ok(_) => continue,
669674
Err((existing_pkg_deps, pkg_deps)) => {
@@ -715,7 +720,7 @@ impl DependencyGraph {
715720
/// available in a package tables of a respective (dependent) subgraph. This function return the
716721
/// right package table, depending on whether conflict was detected between pre-populated
717722
/// combined graph and another sub-graph or between two separate sub-graphs. If we tried to use
718-
/// combined graphs's package table "as is" we would get an error in all cases similar to the on
723+
/// combined graphs's package table "as is" we would get an error in all cases similar to the one
719724
/// in the direct_and_indirect_dep test where A is a direct dependency of Root (as C would be
720725
/// missing from the combined graph's table):
721726
///
@@ -1452,25 +1457,46 @@ fn deps_equal<'a>(
14521457
graph1_pkg_table: &'a BTreeMap<PM::PackageName, Package>,
14531458
graph2: &'a DependencyGraph,
14541459
graph2_pkg_table: &'a BTreeMap<PM::PackageName, Package>,
1460+
overrides: &'a BTreeMap<PM::PackageName, Package>,
14551461
) -> std::result::Result<
14561462
(),
14571463
(
14581464
Vec<(&'a Dependency, PM::PackageName, &'a Package)>,
14591465
Vec<(&'a Dependency, PM::PackageName, &'a Package)>,
14601466
),
14611467
> {
1462-
let graph1_edges = BTreeSet::from_iter(
1463-
graph1
1464-
.package_graph
1465-
.edges(pkg_name)
1466-
.map(|(_, pkg, dep)| (dep, pkg, graph1_pkg_table.get(&pkg).unwrap())),
1467-
);
1468-
let graph2_edges = BTreeSet::from_iter(
1469-
graph2
1470-
.package_graph
1471-
.edges(pkg_name)
1472-
.map(|(_, pkg, dep)| (dep, pkg, graph2_pkg_table.get(&pkg).unwrap())),
1473-
);
1468+
// Unwraps in the code below are safe as these edges (and target nodes) must exist either in the
1469+
// sub-graph or in the pre-populated combined graph (see pkg_table_for_deps_compare's doc
1470+
// comment for a more detailed explanation). If these were to fail, it would indicate a bug in
1471+
// the algorithm so it's OK to panic here.
1472+
let graph1_edges: BTreeSet<_> = graph1
1473+
.package_graph
1474+
.edges(pkg_name)
1475+
.map(|(_, pkg, dep)| {
1476+
(
1477+
dep,
1478+
pkg,
1479+
graph1_pkg_table
1480+
.get(&pkg)
1481+
.or_else(|| overrides.get(&pkg))
1482+
.unwrap(),
1483+
)
1484+
})
1485+
.collect();
1486+
let graph2_edges: BTreeSet<_> = graph2
1487+
.package_graph
1488+
.edges(pkg_name)
1489+
.map(|(_, pkg, dep)| {
1490+
(
1491+
dep,
1492+
pkg,
1493+
graph2_pkg_table
1494+
.get(&pkg)
1495+
.or_else(|| overrides.get(&pkg))
1496+
.unwrap(),
1497+
)
1498+
})
1499+
.collect();
14741500

14751501
let (graph1_pkgs, graph2_pkgs): (Vec<_>, Vec<_>) = graph1_edges
14761502
.symmetric_difference(&graph2_edges)

tools/move-package/tests/test_dependency_graph.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ fn merge_simple() {
234234
}),
235235
)]);
236236
assert!(outer
237-
.merge(dep_graphs, &DependencyKind::default(), dependencies,)
237+
.merge(
238+
dep_graphs,
239+
&DependencyKind::default(),
240+
dependencies,
241+
&BTreeMap::new()
242+
)
238243
.is_ok(),);
239244
assert_eq!(
240245
outer.topological_order(),
@@ -280,7 +285,12 @@ fn merge_into_root() {
280285
}),
281286
)]);
282287
assert!(outer
283-
.merge(dep_graphs, &DependencyKind::default(), dependencies,)
288+
.merge(
289+
dep_graphs,
290+
&DependencyKind::default(),
291+
dependencies,
292+
&BTreeMap::new()
293+
)
284294
.is_ok());
285295

286296
assert_eq!(
@@ -320,6 +330,7 @@ fn merge_detached() {
320330
dep_graphs,
321331
&DependencyKind::default(),
322332
&BTreeMap::new(),
333+
&BTreeMap::new()
323334
) else {
324335
panic!("Inner's root is not part of outer's graph, so this should fail");
325336
};
@@ -354,6 +365,7 @@ fn merge_after_calculating_always_deps() {
354365
dep_graphs,
355366
&DependencyKind::default(),
356367
&BTreeMap::new(),
368+
&BTreeMap::new()
357369
) else {
358370
panic!("Outer's always deps have already been calculated so this should fail");
359371
};
@@ -426,7 +438,12 @@ fn merge_overlapping() {
426438
),
427439
]);
428440
assert!(outer
429-
.merge(dep_graphs, &DependencyKind::default(), dependencies,)
441+
.merge(
442+
dep_graphs,
443+
&DependencyKind::default(),
444+
dependencies,
445+
&BTreeMap::new()
446+
)
430447
.is_ok());
431448
}
432449

@@ -498,6 +515,7 @@ fn merge_overlapping_different_deps() {
498515
dep_graphs,
499516
&DependencyKind::default(),
500517
dependencies,
518+
&BTreeMap::new()
501519
) else {
502520
panic!("Outer and inner mention package A which has different dependencies in both.");
503521
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# @generated by Move, please check-in and do not edit manually.
2+
3+
[move]
4+
version = 0
5+
manifest_digest = "D2FFFC63D2AF7BF7028F583317C7ACF0EBB9E6B9F0DFC6D8FB46732AF7B552E4"
6+
deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3"
7+
8+
dependencies = [
9+
{ name = "More" },
10+
{ name = "Nested" },
11+
{ name = "Shared" },
12+
]
13+
14+
[[move.package]]
15+
name = "More"
16+
source = { local = "deps_only/more" }
17+
18+
dependencies = [
19+
{ name = "Shared" },
20+
]
21+
22+
[[move.package]]
23+
name = "Nested"
24+
source = { local = "deps_only/nested" }
25+
26+
dependencies = [
27+
{ name = "More" },
28+
{ name = "Shared" },
29+
]
30+
31+
[[move.package]]
32+
name = "Shared"
33+
source = { local = "deps_only/shared" }

0 commit comments

Comments
 (0)