Skip to content

Commit 089957f

Browse files
committed
refactor
1 parent 527dc0b commit 089957f

File tree

1 file changed

+142
-117
lines changed

1 file changed

+142
-117
lines changed

src/dfx/src/lib/builders/motoko.rs

Lines changed: 142 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -40,131 +40,24 @@ impl MotokoBuilder {
4040
cache: env.get_cache(),
4141
})
4242
}
43-
}
44-
45-
// TODO: Rename this function.
46-
#[context("Failed to find imports for canister at '{}'.", info.get_main_path().display())]
47-
fn get_imports(cache: &dyn Cache, info: &MotokoCanisterInfo, imports: &mut ImportsTracker, pool: &CanisterPool) -> DfxResult<()> {
48-
#[context("Failed recursive dependency detection at {}.", file.display())]
49-
fn get_imports_recursive (
50-
cache: &dyn Cache,
51-
file: &Path,
52-
imports: &mut ImportsTracker,
53-
pool: &CanisterPool,
54-
) -> DfxResult {
55-
let parent = MotokoImport::Relative(file.to_path_buf());
56-
if imports.nodes.contains_key(&parent) {
57-
return Ok(());
58-
}
59-
let parent_node_index = *imports.nodes.entry(parent.clone()).or_insert_with(|| imports.graph.add_node(parent.clone()));
60-
imports.nodes.insert(parent.clone(), parent_node_index);
61-
62-
let mut command = cache.get_binary_command("moc")?;
63-
let command = command.arg("--print-deps").arg(file);
64-
let output = command
65-
.output()
66-
.with_context(|| format!("Error executing {:#?}", command))?;
67-
let output = String::from_utf8_lossy(&output.stdout);
68-
69-
for line in output.lines() {
70-
let child = MotokoImport::try_from(line).context("Failed to create MotokoImport.")?;
71-
match &child {
72-
MotokoImport::Relative(path) => {
73-
get_imports_recursive(cache, path.as_path(), imports, pool)?;
74-
}
75-
MotokoImport::Canister(canister_name) => { // duplicate code
76-
if let Some(canister) = pool.get_first_canister_with_name(canister_name.as_str()) {
77-
let main_file = canister.get_info().get_main_file();
78-
if let Some(main_file) = main_file {
79-
get_imports_recursive(cache, Path::new(main_file), imports, pool)?;
80-
}
81-
}
82-
}
83-
_ => {}
84-
}
85-
let parent_node_index = *imports.nodes.entry(parent.clone()).or_insert_with(|| imports.graph.add_node(parent.clone()));
86-
let child_node_index = *imports.nodes.entry(child.clone()).or_insert_with(|| imports.graph.add_node(child.clone()));
87-
imports.graph.add_edge(parent_node_index, child_node_index, ());
88-
}
89-
90-
Ok(())
91-
}
92-
93-
get_imports_recursive(cache, info.get_main_path(), imports, pool)?;
94-
95-
Ok(())
96-
}
97-
98-
impl CanisterBuilder for MotokoBuilder {
99-
#[context("Failed to get dependencies for canister '{}'.", info.get_name())]
100-
fn get_dependencies(
101-
&self,
102-
pool: &CanisterPool,
103-
info: &CanisterInfo,
104-
) -> DfxResult<Vec<CanisterId>> {
105-
let motoko_info = info.as_info::<MotokoCanisterInfo>()?;
106-
get_imports(self.cache.as_ref(), &motoko_info, &mut *pool.imports.borrow_mut(), pool)?;
107-
108-
Ok(pool.imports.borrow().nodes
109-
.iter()
110-
.filter_map(|import| {
111-
if let MotokoImport::Canister(name) = import.0 {
112-
pool.get_first_canister_with_name(name.as_str())
113-
} else {
114-
None
115-
}
116-
})
117-
.map(|canister| canister.canister_id())
118-
.collect())
119-
}
12043

121-
#[context("Failed to build Motoko canister '{}'.", canister_info.get_name())]
122-
fn build(
44+
/// Accomplish build given the already calculated canister dependencies
45+
fn do_build(
12346
&self,
12447
pool: &CanisterPool,
12548
canister_info: &CanisterInfo,
12649
config: &BuildConfig,
50+
motoko_info: &MotokoCanisterInfo,
51+
id_map: &BTreeMap<String, String>, // TODO: I feel that this variable should not be here.
52+
rev_id_map: &BTreeMap<String, String>, // TODO: I feel that this variable should not be here.
53+
cache: &dyn Cache,
12754
) -> DfxResult<BuildOutput> {
128-
let motoko_info = canister_info.as_info::<MotokoCanisterInfo>()?;
129-
let profile = config.profile;
130-
let input_path = motoko_info.get_main_path();
13155
let output_wasm_path = motoko_info.get_output_wasm_path();
13256

133-
// from name to principal:
134-
let id_map = pool
135-
.get_canister_list()
136-
.iter()
137-
.map(|c| (c.get_name().to_string(), c.canister_id().to_text()))
138-
.collect();
139-
// from principal to name:
140-
let rev_id_map: BTreeMap<String, String> = pool
141-
.get_canister_list()
142-
.iter()
143-
.map(|c| (c.canister_id().to_text(), c.get_name().to_string()))
144-
.collect();
145-
146-
std::fs::create_dir_all(motoko_info.get_output_root()).with_context(|| {
147-
format!(
148-
"Failed to create {}.",
149-
motoko_info.get_output_root().to_string_lossy()
150-
)
151-
})?;
152-
let cache = &self.cache;
153-
let idl_dir_path = &config.idl_root;
154-
std::fs::create_dir_all(idl_dir_path)
155-
.with_context(|| format!("Failed to create {}.", idl_dir_path.to_string_lossy()))?;
156-
157-
get_imports(cache.as_ref(), &motoko_info, &mut *pool.imports.borrow_mut(), pool)?;
158-
159-
// If the management canister is being imported, emit the candid file.
160-
if pool.imports.borrow().nodes.contains_key(&MotokoImport::Ic("aaaaa-aa".to_string()))
161-
{
162-
let management_idl_path = idl_dir_path.join("aaaaa-aa.did");
163-
dfx_core::fs::write(management_idl_path, management_idl()?)?;
164-
}
165-
57+
let input_path = motoko_info.get_main_path();
58+
let profile = config.profile;
16659
let package_arguments =
167-
package_arguments::load(cache.as_ref(), motoko_info.get_packtool())?;
60+
package_arguments::load(cache, motoko_info.get_packtool())?;
16861
let mut package_arguments_map = BTreeMap::<String, String>::new(); // TODO: Can we deal without cloning strings?
16962
{ // block
17063
let mut i = 0;
@@ -271,6 +164,17 @@ impl CanisterBuilder for MotokoBuilder {
271164
}
272165
};
273166

167+
let idl_dir_path = &config.idl_root;
168+
std::fs::create_dir_all(idl_dir_path)
169+
.with_context(|| format!("Failed to create {}.", idl_dir_path.to_string_lossy()))?;
170+
171+
// If the management canister is being imported, emit the candid file.
172+
if pool.imports.borrow().nodes.contains_key(&MotokoImport::Ic("aaaaa-aa".to_string()))
173+
{
174+
let management_idl_path = idl_dir_path.join("aaaaa-aa.did");
175+
dfx_core::fs::write(management_idl_path, management_idl()?)?;
176+
}
177+
274178
let moc_arguments = match motoko_info.get_args() {
275179
Some(args) => [
276180
package_arguments,
@@ -305,7 +209,7 @@ impl CanisterBuilder for MotokoBuilder {
305209
idl_path: idl_dir_path,
306210
idl_map: &id_map,
307211
};
308-
motoko_compile(&self.logger, cache.as_ref(), &params)?;
212+
motoko_compile(&self.logger, cache, &params)?;
309213

310214
Ok(BuildOutput { // duplicate code
311215
canister_id: canister_info
@@ -315,6 +219,127 @@ impl CanisterBuilder for MotokoBuilder {
315219
idl: IdlBuildOutput::File(motoko_info.get_output_idl_path().to_path_buf()),
316220
})
317221
}
222+
223+
}
224+
225+
// TODO: Rename this function.
226+
#[context("Failed to find imports for canister at '{}'.", info.get_main_path().display())]
227+
fn get_imports(cache: &dyn Cache, info: &MotokoCanisterInfo, imports: &mut ImportsTracker, pool: &CanisterPool) -> DfxResult<()> {
228+
#[context("Failed recursive dependency detection at {}.", file.display())]
229+
fn get_imports_recursive (
230+
cache: &dyn Cache,
231+
file: &Path,
232+
imports: &mut ImportsTracker,
233+
pool: &CanisterPool,
234+
) -> DfxResult {
235+
let parent = MotokoImport::Relative(file.to_path_buf());
236+
if imports.nodes.contains_key(&parent) {
237+
return Ok(());
238+
}
239+
let parent_node_index = *imports.nodes.entry(parent.clone()).or_insert_with(|| imports.graph.add_node(parent.clone()));
240+
imports.nodes.insert(parent.clone(), parent_node_index);
241+
242+
let mut command = cache.get_binary_command("moc")?;
243+
let command = command.arg("--print-deps").arg(file);
244+
let output = command
245+
.output()
246+
.with_context(|| format!("Error executing {:#?}", command))?;
247+
let output = String::from_utf8_lossy(&output.stdout);
248+
249+
for line in output.lines() {
250+
let child = MotokoImport::try_from(line).context("Failed to create MotokoImport.")?;
251+
match &child {
252+
MotokoImport::Relative(path) => {
253+
get_imports_recursive(cache, path.as_path(), imports, pool)?;
254+
}
255+
MotokoImport::Canister(canister_name) => { // duplicate code
256+
if let Some(canister) = pool.get_first_canister_with_name(canister_name.as_str()) {
257+
let main_file = canister.get_info().get_main_file();
258+
if let Some(main_file) = main_file {
259+
get_imports_recursive(cache, Path::new(main_file), imports, pool)?;
260+
}
261+
}
262+
}
263+
_ => {}
264+
}
265+
let parent_node_index = *imports.nodes.entry(parent.clone()).or_insert_with(|| imports.graph.add_node(parent.clone()));
266+
let child_node_index = *imports.nodes.entry(child.clone()).or_insert_with(|| imports.graph.add_node(child.clone()));
267+
imports.graph.add_edge(parent_node_index, child_node_index, ());
268+
}
269+
270+
Ok(())
271+
}
272+
273+
get_imports_recursive(cache, info.get_main_path(), imports, pool)?;
274+
275+
Ok(())
276+
}
277+
278+
impl CanisterBuilder for MotokoBuilder {
279+
#[context("Failed to get dependencies for canister '{}'.", info.get_name())]
280+
fn get_dependencies(
281+
&self,
282+
pool: &CanisterPool,
283+
info: &CanisterInfo,
284+
) -> DfxResult<Vec<CanisterId>> {
285+
let motoko_info = info.as_info::<MotokoCanisterInfo>()?;
286+
get_imports(self.cache.as_ref(), &motoko_info, &mut *pool.imports.borrow_mut(), pool)?;
287+
288+
Ok(pool.imports.borrow().nodes
289+
.iter()
290+
.filter_map(|import| {
291+
if let MotokoImport::Canister(name) = import.0 {
292+
pool.get_first_canister_with_name(name.as_str())
293+
} else {
294+
None
295+
}
296+
})
297+
.map(|canister| canister.canister_id())
298+
.collect())
299+
}
300+
301+
#[context("Failed to build Motoko canister '{}'.", canister_info.get_name())]
302+
fn build(
303+
&self,
304+
pool: &CanisterPool,
305+
canister_info: &CanisterInfo,
306+
config: &BuildConfig,
307+
) -> DfxResult<BuildOutput> {
308+
let motoko_info = canister_info.as_info::<MotokoCanisterInfo>()?;
309+
310+
// from name to principal:
311+
let id_map = pool
312+
.get_canister_list()
313+
.iter()
314+
.map(|c| (c.get_name().to_string(), c.canister_id().to_text()))
315+
.collect();
316+
// from principal to name:
317+
let rev_id_map: BTreeMap<String, String> = pool
318+
.get_canister_list()
319+
.iter()
320+
.map(|c| (c.canister_id().to_text(), c.get_name().to_string()))
321+
.collect();
322+
323+
std::fs::create_dir_all(motoko_info.get_output_root()).with_context(|| {
324+
format!(
325+
"Failed to create {}.",
326+
motoko_info.get_output_root().to_string_lossy()
327+
)
328+
})?;
329+
let cache = &self.cache;
330+
331+
get_imports(cache.as_ref(), &motoko_info, &mut *pool.imports.borrow_mut(), pool)?;
332+
333+
self.do_build(
334+
pool,
335+
canister_info,
336+
config,
337+
&motoko_info,
338+
&id_map,
339+
&rev_id_map,
340+
cache.as_ref(),
341+
)
342+
}
318343

319344
fn get_candid_path(
320345
&self,

0 commit comments

Comments
 (0)