@@ -7,6 +7,7 @@ use crate::lib::environment::Environment;
7
7
use crate :: lib:: error:: { BuildError , DfxError , DfxResult } ;
8
8
use crate :: lib:: metadata:: dfx:: DfxMetadata ;
9
9
use crate :: lib:: metadata:: names:: { CANDID_ARGS , CANDID_SERVICE , DFX } ;
10
+ use crate :: lib:: operations:: canister;
10
11
use crate :: lib:: wasm:: file:: { compress_bytes, read_wasm_module} ;
11
12
use crate :: util:: assets;
12
13
use anyhow:: { anyhow, bail, Context } ;
@@ -21,6 +22,7 @@ use ic_wasm::metadata::{add_metadata, remove_metadata, Kind};
21
22
use ic_wasm:: optimize:: OptLevel ;
22
23
use itertools:: Itertools ;
23
24
use petgraph:: graph:: { DiGraph , NodeIndex } ;
25
+ use petgraph:: visit:: Dfs ;
24
26
use rand:: { thread_rng, RngCore } ;
25
27
use slog:: { error, info, trace, warn, Logger } ;
26
28
use std:: cell:: RefCell ;
@@ -572,21 +574,58 @@ impl CanisterPool {
572
574
}
573
575
}
574
576
575
- println ! ( "GRAPH2: {:?}" , self . imports. borrow( ) . graph) ;
576
- // FIXME: Error on indirect dependencies.
577
- Ok ( self . imports . borrow ( ) . graph . filter_map (
578
- |_node_index, node_weight| {
579
- match node_weight {
580
- // FIXME: The "tops" of the digraph are `Relative()`, not `Canister()`
581
- // TODO: `get_first_canister_with_name` is a hack
582
- MotokoImport :: Canister ( name) => Some ( self . get_first_canister_with_name ( & name) . unwrap ( ) . canister_id ( ) ) ,
583
- _ => None ,
577
+ let real_canisters_to_build = match canisters_to_build {
578
+ Some ( canisters_to_build) => canisters_to_build,
579
+ None => self . canisters . iter ( ) . map ( |canister| canister. get_name ( ) . to_string ( ) ) . collect ( ) ,
580
+ } ;
581
+ // Transform the graph of file dependencies to graph of canister dependencies.
582
+ // For this do DFS for each of `real_canisters_to_build`.
583
+ let source_graph = & self . imports . borrow ( ) . graph ;
584
+ let mut dest_graph: DiGraph < CanisterId , ( ) > = DiGraph :: new ( ) ;
585
+ let mut dest_id_set = HashMap :: new ( ) ;
586
+ let mut name_to_dest = HashMap :: new ( ) ;
587
+ for start_name in real_canisters_to_build. iter ( ) {
588
+ let dest_start = self . get_first_canister_with_name ( & start_name) . unwrap ( ) . canister_id ( ) ;
589
+ let dest_start = * dest_id_set. entry ( dest_start. clone ( ) ) . or_insert_with ( || dest_graph. add_node ( dest_start. clone ( ) ) ) ; // TODO: always inserts
590
+ name_to_dest. insert ( start_name, dest_start) ;
591
+ let mut iter = Dfs :: new ( & source_graph, dest_start) ;
592
+ iter. next ( & source_graph) ;
593
+ while let Some ( cur_source_id) = iter. next ( & source_graph) {
594
+ let cur_source_node = source_graph. node_weight ( cur_source_id) . unwrap ( ) ;
595
+ if let MotokoImport :: Canister ( name) = cur_source_node {
596
+ let parent_in_source_id = * iter. stack . iter ( ) . rev ( ) . find (
597
+ |& entry|
598
+ if let Some ( MotokoImport :: Canister ( _parent_name) ) = source_graph. node_weight ( * entry) {
599
+ true
600
+ } else {
601
+ false
602
+ }
603
+ ) . unwrap ( ) ;
604
+ // Both parent and current ancestor are `Canister` dependencies.
605
+ let parent_in_dest_id =
606
+ name_to_dest. entry ( parent_in_source_id) . or_insert_with ( || dest_graph. add_node ( cur_canister_id) ) ;
607
+ dest_graph. add_edge ( parent_in_dest_id, b, ( ) )
608
+ // let parent_in_source = source_graph.node_weight(*parent_in_source).unwrap();
584
609
}
585
- } ,
586
- |_edge_index, _edge_weight| {
587
- Some ( ( ) )
610
+ // let cur_node_id = id_set.entry(cur_source_id).or_insert_with(|| id_set.insert(cur_source_id));
588
611
}
589
- ) )
612
+ }
613
+
614
+ Ok ( dest_graph)
615
+ // FIXME: Wrong behavior on indirect dependencies.
616
+ // Ok(self.imports.borrow().graph.filter_map(
617
+ // |_node_index, node_weight| {
618
+ // match node_weight {
619
+ // // FIXME: The "tops" of the digraph are `Relative()`, not `Canister()`
620
+ // // TODO: `get_first_canister_with_name` is a hack
621
+ // MotokoImport::Canister(name) => Some(self.get_first_canister_with_name(&name).unwrap().canister_id()),
622
+ // _ => None,
623
+ // }
624
+ // },
625
+ // |_edge_index, _edge_weight| {
626
+ // Some(())
627
+ // }
628
+ // ))
590
629
}
591
630
592
631
#[ context( "Failed step_prebuild_all." ) ]
0 commit comments