1use std::env::current_dir;
10use std::env::set_current_dir;
11use std::env::split_paths;
12use std::ffi::OsString;
13#[cfg(target_family = "unix")]
14use std::fs;
15use std::fs::File;
16use std::fs::create_dir_all;
17use std::fs::remove_dir;
18#[cfg(target_family = "unix")]
19use std::fs::set_permissions;
20use std::io;
21use std::io::stdout;
22use std::io::BufWriter;
23use std::io::Write;
24#[cfg(target_family = "unix")]
25use std::os::unix::fs::PermissionsExt;
26use std::path;
27use std::path::Path;
28use std::path::PathBuf;
29use std::sync::Arc;
30use std::sync::RwLock;
31use crate::toml;
32use crate::backend::*;
33use crate::error::*;
34use crate::fs::*;
35use crate::home::*;
36use crate::main_loop::*;
37use crate::mod_node::*;
38use crate::pkg;
39use crate::pkg::*;
40use crate::tester;
41use crate::tester::*;
42use crate::utils::*;
43use crate::value::*;
44
45fn create_home<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, is_work_dir: bool, f: F) -> Option<Home>
46 where F: FnOnce(&mut Home) -> bool
47{
48 match Home::new(home_dir, bin_path, lib_path, doc_path, is_work_dir) {
49 Some(mut home) => {
50 if !f(&mut home) {
51 return None;
52 }
53 Some(home)
54 },
55 None => {
56 eprintln!("no unlab-gpu home directory");
57 None
58 },
59 }
60}
61
62fn create_pkg_manager<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, is_work_dir: bool, f: F) -> Option<PkgManager>
63 where F: FnOnce(&mut Home) -> bool
64{
65 let home = create_home(home_dir, bin_path, lib_path, doc_path, is_work_dir, f)?;
66 let home_dir = PathBuf::from(home.home_dir());
67 let work_dir = if !is_work_dir {
68 PathBuf::from(home.home_dir())
69 } else {
70 PathBuf::from("work")
71 };
72 let bin_dir = match split_paths(home.bin_path()).next() {
73 Some(tmp_bin_dir) => PathBuf::from(tmp_bin_dir),
74 None => {
75 eprintln!("no binary directory");
76 return None;
77 },
78 };
79 let lib_dir = match split_paths(home.lib_path()).next() {
80 Some(tmp_lib_dir) => PathBuf::from(tmp_lib_dir),
81 None => {
82 eprintln!("no library directory");
83 return None;
84 },
85 };
86 let doc_dir = match split_paths(home.doc_path()).next() {
87 Some(tmp_doc_dir) => PathBuf::from(tmp_doc_dir),
88 None => {
89 eprintln!("no documentation directory");
90 return None;
91 },
92 };
93 if is_work_dir {
94 match PkgManager::manifest() {
95 Ok(_) => (),
96 Err(err) => {
97 eprint_error(&err);
98 return None;
99 },
100 }
101 }
102 match PkgManager::new(home_dir, work_dir, bin_dir, lib_dir, doc_dir, src_factories, Arc::new(pkg::StdPrinter::new())) {
103 Ok(pkg_manager) => Some(pkg_manager),
104 Err(err) => {
105 eprint_error(&err);
106 None
107 },
108 }
109}
110
111fn parse_pkg_name(s: &str) -> Option<PkgName>
112{
113 match PkgName::parse(s) {
114 Ok(pkg_name) => Some(pkg_name),
115 Err(err) => {
116 eprint_error(&err);
117 None
118 },
119 }
120}
121
122fn parse_pkg_names(ss: &[String]) -> Option<Vec<PkgName>>
123{
124 let mut pkg_names: Vec<PkgName> = Vec::new();
125 for s in ss {
126 pkg_names.push(parse_pkg_name(s.as_str())?);
127 }
128 Some(pkg_names)
129}
130
131fn parse_idents(s: &str) -> Vec<String>
132{
133 let s_without_first_colons = if s.starts_with("::") {
134 &s[2..]
135 } else {
136 s
137 };
138 let idents: Vec<String> = s_without_first_colons.split("::").map(String::from).collect();
139 match idents.first() {
140 Some(ident) if ident == &String::from("root") => (&idents[1..]).to_vec(),
141 Some(_) => idents,
142 None => Vec::new(),
143 }
144}
145
146fn parse_idents_and_ident(s: &str) -> Option<(Vec<String>, String)>
147{
148 let idents = parse_idents(s);
149 match idents.last() {
150 Some(ident) => Some(((&idents[0..(idents.len() - 1)]).to_vec(), ident.clone())),
151 None => {
152 eprintln!("invalid test name");
153 None
154 },
155 }
156}
157
158fn res_list(pkg_manager: &PkgManager, are_deps: bool) -> Result<()>
159{
160 pkg_manager.check_last_op(are_deps)?;
161 pkg_manager.pkg_versions_in(|name, version| {
162 println!("{} v{}", name, version);
163 Ok(())
164 })?;
165 Ok(())
166}
167
168fn list_with_dep_flag<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
169 where F: FnOnce(&mut Home) -> bool
170{
171 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
172 Some(tmp_pkg_manager) => tmp_pkg_manager,
173 None => return Some(1),
174 };
175 match res_list(&pkg_manager, are_deps) {
176 Ok(()) => None,
177 Err(err) => {
178 pkg_manager.printer().print_lf_for_error();
179 eprint_error(&err);
180 Some(1)
181 },
182 }
183}
184
185pub fn list<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
187 where F: FnOnce(&mut Home) -> bool
188{ list_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
189
190pub fn list_deps<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
192 where F: FnOnce(&mut Home) -> bool
193{ list_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
194
195fn res_search(pkg_manager: &PkgManager, patterns :&[String], are_deps: bool) -> Result<()>
196{
197 pkg_manager.check_last_op(are_deps)?;
198 pkg_manager.pkg_versions_in(|name, version| {
199 match pkg_manager.pkg_manifest(name)? {
200 Some(manifest) => {
201 if patterns.iter().all(|p| name.name().contains(p.as_str()) || manifest.package.description.as_ref().map(|d| d.contains(p.as_str())).unwrap_or(false)) {
202 println!("{} v{}", name, version);
203 }
204 },
205 None => (),
206 }
207 Ok(())
208 })?;
209 Ok(())
210}
211
212fn search_with_dep_flag<F>(patterns :&[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
213 where F: FnOnce(&mut Home) -> bool
214{
215 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
216 Some(tmp_pkg_manager) => tmp_pkg_manager,
217 None => return Some(1),
218 };
219 match res_search(&pkg_manager, patterns, are_deps) {
220 Ok(()) => None,
221 Err(err) => {
222 pkg_manager.printer().print_lf_for_error();
223 eprint_error(&err);
224 Some(1)
225 },
226 }
227}
228
229pub fn search<F>(patterns :&[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
231 where F: FnOnce(&mut Home) -> bool
232{ search_with_dep_flag(patterns, home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
233
234pub fn search_deps<F>(patterns :&[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
236 where F: FnOnce(&mut Home) -> bool
237{ search_with_dep_flag(patterns, home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
238
239fn res_show(pkg_manager: &PkgManager, pkg_name: &PkgName, is_manifest: bool, are_dependents: bool, are_paths: bool, is_dep: bool) -> Result<()>
240{
241 pkg_manager.check_last_op(is_dep)?;
242 let version = match pkg_manager.pkg_version(pkg_name)? {
243 Some(tmp_version) => tmp_version,
244 None => return Err(Error::PkgName(pkg_name.clone(), String::from("not found package"))),
245 };
246 let manifest = match pkg_manager.pkg_manifest(pkg_name)? {
247 Some(tmp_manifest) => tmp_manifest,
248 None => return Err(Error::PkgName(pkg_name.clone(), String::from("no package manifest"))),
249 };
250 let dependents = match pkg_manager.pkg_dependents(pkg_name)? {
251 Some(tmp_dependents) => tmp_dependents,
252 None => return Err(Error::PkgName(pkg_name.clone(), String::from("no package dependents"))),
253 };
254 let paths = match pkg_manager.pkg_paths(pkg_name)? {
255 Some(tmp_paths) => tmp_paths,
256 None => return Err(Error::PkgName(pkg_name.clone(), String::from("no package paths"))),
257 };
258 println!("{} v{}", pkg_name, version);
259 if is_manifest || (!is_manifest && !are_dependents && !are_paths) {
260 println!("Manifest:");
261 match toml::to_string_pretty(&manifest) {
262 Ok(s) => println!("{}", s),
263 Err(err) => return Err(Error::TomlSer(err)),
264 }
265 }
266 if are_dependents {
267 println!("Dependents:");
268 match toml::to_string_pretty(&dependents) {
269 Ok(s) => println!("{}", s),
270 Err(err) => return Err(Error::TomlSer(err)),
271 }
272 }
273 if are_paths {
274 println!("Paths:");
275 match toml::to_string_pretty(&paths) {
276 Ok(s) => println!("{}", s),
277 Err(err) => return Err(Error::TomlSer(err)),
278 }
279 }
280 Ok(())
281}
282
283fn show_with_dep_flag<F>(name :&str, is_manifest: bool, are_dependents: bool, are_paths: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, is_dep: bool, f: F) -> Option<i32>
284 where F: FnOnce(&mut Home) -> bool
285{
286 let pkg_name = match parse_pkg_name(name) {
287 Some(tmp_pkg_name) => tmp_pkg_name,
288 None => return Some(1),
289 };
290 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, is_dep, f) {
291 Some(tmp_pkg_manager) => tmp_pkg_manager,
292 None => return Some(1),
293 };
294 match res_show(&pkg_manager, &pkg_name, is_manifest, are_dependents, are_paths, is_dep) {
295 Ok(()) => None,
296 Err(err) => {
297 pkg_manager.printer().print_lf_for_error();
298 eprint_error(&err);
299 Some(1)
300 },
301 }
302}
303
304pub fn show<F>(name :&str, is_manifest: bool, are_dependents: bool, are_paths: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
306 where F: FnOnce(&mut Home) -> bool
307{ show_with_dep_flag(name, is_manifest, are_dependents, are_paths, home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
308
309pub fn show_dep<F>(name :&str, is_manifest: bool, are_dependents: bool, are_paths: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
311 where F: FnOnce(&mut Home) -> bool
312{ show_with_dep_flag(name, is_manifest, are_dependents, are_paths, home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
313
314fn res_update(pkg_manager: &PkgManager, pkg_names: &[PkgName], are_deps: bool) -> Result<()>
315{
316 pkg_manager.check_last_op(are_deps)?;
317 if pkg_names.is_empty() {
318 pkg_manager.update_all()?;
319 } else {
320 pkg_manager.update(pkg_names)?;
321 }
322 Ok(())
323}
324
325fn update_with_dep_flag<F>(names: &[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
326 where F: FnOnce(&mut Home) -> bool
327{
328 let pkg_names = match parse_pkg_names(names) {
329 Some(tmp_pkg_names) => tmp_pkg_names,
330 None => return Some(1),
331 };
332 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
333 Some(tmp_pkg_manager) => tmp_pkg_manager,
334 None => return Some(1),
335 };
336 match res_update(&pkg_manager, pkg_names.as_slice(), are_deps) {
337 Ok(()) => None,
338 Err(err) => {
339 pkg_manager.printer().print_lf_for_error();
340 eprint_error(&err);
341 Some(1)
342 },
343 }
344}
345
346pub fn update<F>(names: &[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
348 where F: FnOnce(&mut Home) -> bool
349{ update_with_dep_flag(names, home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
350
351pub fn update_deps<F>(names: &[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
353 where F: FnOnce(&mut Home) -> bool
354{ update_with_dep_flag(names, home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
355
356fn res_install(pkg_manager: &mut PkgManager, pkg_names: &[PkgName], is_update: bool, is_force: bool, is_doc: bool) -> Result<()>
357{
358 pkg_manager.check_last_op(false)?;
359 pkg_manager.load_constraints()?;
360 pkg_manager.load_sources()?;
361 pkg_manager.install(pkg_names, is_update, is_force, is_doc)?;
362 Ok(())
363}
364
365pub fn install<F>(names: &[String], is_update: bool, is_force: bool, is_doc: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
367 where F: FnOnce(&mut Home) -> bool
368{
369 let pkg_names = match parse_pkg_names(names) {
370 Some(tmp_pkg_names) => tmp_pkg_names,
371 None => return Some(1),
372 };
373 let mut pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) {
374 Some(tmp_pkg_manager) => tmp_pkg_manager,
375 None => return Some(1),
376 };
377 match res_install(&mut pkg_manager, pkg_names.as_slice(), is_update, is_force, is_doc) {
378 Ok(()) => None,
379 Err(err) => {
380 pkg_manager.printer().print_lf_for_error();
381 eprint_error(&err);
382 Some(1)
383 },
384 }
385}
386
387fn res_install_all(pkg_manager: &mut PkgManager, is_update: bool, is_force: bool, is_doc: bool) -> Result<()>
388{
389 pkg_manager.check_last_op(false)?;
390 pkg_manager.load_constraints()?;
391 pkg_manager.load_sources()?;
392 pkg_manager.install_all(is_update, is_force, is_doc)?;
393 Ok(())
394}
395
396pub fn install_all<F>(is_update: bool, is_force: bool, is_doc: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
398 where F: FnOnce(&mut Home) -> bool
399{
400 let mut pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) {
401 Some(tmp_pkg_manager) => tmp_pkg_manager,
402 None => return Some(1),
403 };
404 match res_install_all(&mut pkg_manager, is_update, is_force, is_doc) {
405 Ok(()) => None,
406 Err(err) => {
407 pkg_manager.printer().print_lf_for_error();
408 eprint_error(&err);
409 Some(1)
410 },
411 }
412}
413
414fn res_install_deps(pkg_manager: &mut PkgManager, is_update: bool, is_force: bool, is_doc: bool, is_locked: bool, is_unlocked: bool) -> Result<()>
415{
416 pkg_manager.check_last_op(true)?;
417 if (!is_update || is_locked) && (!is_unlocked || is_locked) {
418 pkg_manager.load_locks()?;
419 }
420 pkg_manager.install_deps(is_update, is_force, is_doc)?;
421 pkg_manager.save_locks_from_pkg_versions()?;
422 Ok(())
423}
424
425pub fn install_deps<F>(is_update: bool, is_force: bool, is_doc: bool, is_locked: bool, is_unlocked: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
427 where F: FnOnce(&mut Home) -> bool
428{
429 let mut pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) {
430 Some(tmp_pkg_manager) => tmp_pkg_manager,
431 None => return Some(1),
432 };
433 match res_install_deps(&mut pkg_manager, is_update, is_force, is_doc, is_locked, is_unlocked) {
434 Ok(()) => None,
435 Err(err) => {
436 pkg_manager.printer().print_lf_for_error();
437 eprint_error(&err);
438 Some(1)
439 },
440 }
441}
442
443fn res_remove(pkg_manager: &mut PkgManager, pkg_names: &[PkgName]) -> Result<()>
444{
445 pkg_manager.check_last_op(false)?;
446 pkg_manager.remove(pkg_names)?;
447 Ok(())
448}
449
450pub fn remove<F>(names: &[String], home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
452 where F: FnOnce(&mut Home) -> bool
453{
454 let pkg_names = match parse_pkg_names(names) {
455 Some(tmp_pkg_names) => tmp_pkg_names,
456 None => return Some(1),
457 };
458 let mut pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) {
459 Some(tmp_pkg_manager) => tmp_pkg_manager,
460 None => return Some(1),
461 };
462 match res_remove(&mut pkg_manager, pkg_names.as_slice()) {
463 Ok(()) => None,
464 Err(err) => {
465 pkg_manager.printer().print_lf_for_error();
466 eprint_error(&err);
467 Some(1)
468 },
469 }
470}
471
472fn check_with_dep_flag<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
473 where F: FnOnce(&mut Home) -> bool
474{
475 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
476 Some(tmp_pkg_manager) => tmp_pkg_manager,
477 None => return Some(1),
478 };
479 match pkg_manager.check_last_op(are_deps) {
480 Ok(()) => None,
481 Err(err) => {
482 pkg_manager.printer().print_lf_for_error();
483 eprint_error(&err);
484 Some(1)
485 },
486 }
487}
488
489pub fn check<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
491 where F: FnOnce(&mut Home) -> bool
492{ check_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
493
494pub fn check_deps<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
496 where F: FnOnce(&mut Home) -> bool
497{ check_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
498
499fn res_continue(pkg_manager: &PkgManager, is_doc: bool, are_deps: bool) -> Result<()>
500{
501 pkg_manager.cont(is_doc, are_deps)?;
502 if are_deps {
503 pkg_manager.save_locks_from_pkg_versions()?;
504 }
505 Ok(())
506}
507
508fn continue_with_dep_flag<F>(is_doc: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
509 where F: FnOnce(&mut Home) -> bool
510{
511 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
512 Some(tmp_pkg_manager) => tmp_pkg_manager,
513 None => return Some(1),
514 };
515 match res_continue(&pkg_manager, is_doc, are_deps) {
516 Ok(()) => None,
517 Err(err) => {
518 pkg_manager.printer().print_lf_for_error();
519 eprint_error(&err);
520 Some(1)
521 },
522 }
523}
524
525pub fn cont<F>(is_doc: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
527 where F: FnOnce(&mut Home) -> bool
528{ continue_with_dep_flag(is_doc, home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
529
530pub fn continue_deps<F>(is_doc: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
532 where F: FnOnce(&mut Home) -> bool
533{ continue_with_dep_flag(is_doc, home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
534
535fn clean_with_dep_flag<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
536 where F: FnOnce(&mut Home) -> bool
537{
538 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
539 Some(tmp_pkg_manager) => tmp_pkg_manager,
540 None => return Some(1),
541 };
542 match pkg_manager.clean() {
543 Ok(()) => None,
544 Err(err) => {
545 pkg_manager.printer().print_lf_for_error();
546 eprint_error(&err);
547 Some(1)
548 },
549 }
550}
551
552pub fn clean<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
554 where F: FnOnce(&mut Home) -> bool
555{ clean_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
556
557pub fn clean_deps<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
559 where F: FnOnce(&mut Home) -> bool
560{ clean_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }
561
562fn res_lock(pkg_manager: &PkgManager) -> Result<()>
563{
564 pkg_manager.check_last_op(true)?;
565 pkg_manager.save_locks_from_pkg_versions()?;
566 Ok(())
567}
568
569pub fn lock<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
571 where F: FnOnce(&mut Home) -> bool
572{
573 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) {
574 Some(tmp_pkg_manager) => tmp_pkg_manager,
575 None => return Some(1),
576 };
577 match res_lock(&pkg_manager) {
578 Ok(()) => None,
579 Err(err) => {
580 pkg_manager.printer().print_lf_for_error();
581 eprint_error(&err);
582 Some(1)
583 },
584 }
585}
586
587fn io_res_clean_dir<P: AsRef<Path>>(dir: P, msg: &str) -> io::Result<()>
588{
589 print!("{}", msg);
590 let _res = stdout().flush();
591 recursively_remove(dir, true)?;
592 println!(" done");
593 Ok(())
594}
595
596pub fn clean_index<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
598 where F: FnOnce(&mut Home) -> bool
599{
600 let home = match create_home(home_dir, bin_path, lib_path, doc_path, false, f) {
601 Some(tmp_home) => tmp_home,
602 None => return Some(1),
603 };
604 match io_res_clean_dir(index_dir(home.home_dir()), "Cleaning index ...") {
605 Ok(()) => None,
606 Err(err) => {
607 println!("");
608 eprint_error(&Error::Io(err));
609 Some(1)
610 },
611 }
612}
613
614pub fn clean_cache<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
616 where F: FnOnce(&mut Home) -> bool
617{
618 let home = match create_home(home_dir, bin_path, lib_path, doc_path, false, f) {
619 Some(tmp_home) => tmp_home,
620 None => return Some(1),
621 };
622 match io_res_clean_dir(cache_dir(home.home_dir()), "Cleaning cache ...") {
623 Ok(()) => None,
624 Err(err) => {
625 println!("");
626 eprint_error(&Error::Io(err));
627 Some(1)
628 },
629 }
630}
631
632fn res_clean_work() -> Result<()>
633{
634 PkgManager::manifest()?;
635 match io_res_clean_dir("work", "Cleaning work ...") {
636 Ok(()) => Ok(()),
637 Err(err) => {
638 println!("");
639 Err(Error::Io(err))
640 },
641 }
642}
643
644pub fn clean_work<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
646 where F: FnOnce(&mut Home) -> bool
647{
648 match create_home(home_dir, bin_path, lib_path, doc_path, true, f) {
649 Some(_) => (),
650 None => return Some(1),
651 }
652 match res_clean_work() {
653 Ok(()) => None,
654 Err(err) => {
655 eprint_error(&err);
656 Some(1)
657 },
658 }
659}
660
661fn res_config(home: &Home, account: &Option<String>, domain: &Option<String>) -> Result<()>
662{
663 let config = PkgConfig::load_opt(home.pkg_config_file())?;
664 if account.is_none() && domain.is_none() {
665 println!("Configuration:");
666 match &config {
667 Some(config) => {
668 match toml::to_string_pretty(&config) {
669 Ok(s) => println!("{}", s),
670 Err(err) => return Err(Error::TomlSer(err)),
671 }
672 },
673 None => println!(""),
674 }
675 } else {
676 let mut old_account: Option<String> = None;
677 let mut old_domain: Option<String> = None;
678 match config {
679 Some(config) => {
680 old_account = config.account.clone();
681 old_domain = config.domain.clone();
682 },
683 None => (),
684 }
685 let new_config = PkgConfig::new(account.clone().or(old_account), domain.clone().or(old_domain));
686 new_config.save(home.pkg_config_file())?;
687 }
688 Ok(())
689}
690
691pub fn config<F>(account: &Option<String>, domain: &Option<String>, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
693 where F: FnOnce(&mut Home) -> bool
694{
695 let home = match create_home(home_dir, bin_path, lib_path, doc_path, false, f) {
696 Some(tmp_home) => tmp_home,
697 None => return Some(1),
698 };
699 match res_config(&home, account, domain) {
700 Ok(()) => None,
701 Err(err) => {
702 eprint_error(&err);
703 Some(1)
704 },
705 }
706}
707
708fn io_res_init(bin_name: &str, lib_name: &str, is_bin: bool, is_lib: bool, are_tests: bool) -> io::Result<()>
709{
710 {
711 let file = File::create(".gitignore")?;
712 let mut w = BufWriter::new(file);
713 writeln!(&mut w, "/work")?;
714 }
715 if is_bin {
716 let mut path_buf = PathBuf::from("bin");
717 create_dir_all(path_buf.as_path())?;
718 path_buf.push(bin_name);
719 let file = File::create(path_buf.as_path())?;
720 let mut w = BufWriter::new(file);
721 writeln!(&mut w, "#!/usr/bin/env unlab-gpu --")?;
722 writeln!(&mut w, "")?;
723 writeln!(&mut w, "println(\"Hello world!!!\")")?;
724 #[cfg(target_family = "unix")]
725 let mut perms = fs::metadata(path_buf.as_path())?.permissions();
726 #[cfg(target_family = "unix")]
727 perms.set_mode(perms.mode() | ((perms.mode() >> 2) & 0o111));
728 #[cfg(target_family = "unix")]
729 set_permissions(path_buf.as_path(), perms)?;
730 }
731 if is_lib || (!is_bin && !is_lib) {
732 let mut path_buf = PathBuf::from("lib");
733 path_buf.push(lib_name.replace('/', path::MAIN_SEPARATOR_STR));
734 create_dir_all(path_buf.as_path())?;
735 path_buf.push("lib.un");
736 let file = File::create(path_buf)?;
737 let mut w = BufWriter::new(file);
738 writeln!(&mut w, "module {}", str_to_ident(lib_name))?;
739 writeln!(&mut w, " function add(x, y)")?;
740 writeln!(&mut w, " x + y")?;
741 writeln!(&mut w, " end")?;
742 writeln!(&mut w, "end")?;
743 }
744 if are_tests {
745 let mut path_buf = PathBuf::from("tests");
746 path_buf.push(lib_name.replace('/', path::MAIN_SEPARATOR_STR));
747 create_dir_all(path_buf.as_path())?;
748 path_buf.push("tests.un");
749 let file = File::create(path_buf)?;
750 let mut w = BufWriter::new(file);
751 let lib_name_without_domain = match lib_name.split_once('/') {
752 Some((_, tmp_lib_name_without_domain)) => tmp_lib_name_without_domain,
753 None => lib_name,
754 };
755 writeln!(&mut w, "uselib(\"{}\")", lib_name_without_domain)?;
756 writeln!(&mut w, "")?;
757 writeln!(&mut w, "module {}_tests", str_to_ident(lib_name))?;
758 writeln!(&mut w, " tests()")?;
759 writeln!(&mut w, " usevars(\"{}\")", str_to_ident(lib_name))?;
760 writeln!(&mut w, "")?;
761 writeln!(&mut w, " function test_add_adds()")?;
762 writeln!(&mut w, " asserteq(4, add(2, 2))")?;
763 writeln!(&mut w, " end")?;
764 writeln!(&mut w, "end")?;
765 }
766 Ok(())
767}
768
769fn res_init(pkg_name: &PkgName, bin_name: &str, lib_name: &str, is_bin: bool, is_lib: bool, are_tests: bool) -> Result<()>
770{
771 let manifest = Manifest::new(pkg_name.clone());
772 PkgManager::save_manifest(&manifest)?;
773 match io_res_init(bin_name, lib_name, is_bin, is_lib, are_tests) {
774 Ok(()) => Ok(()),
775 Err(err) => Err(Error::Io(err)),
776 }
777}
778
779pub fn init<F>(path: &Option<String>, name: &Option<String>, account: &Option<String>, domain: &Option<String>, is_bin: bool, is_lib: bool, are_tests: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
781 where F: FnOnce(&mut Home) -> bool
782{
783 match path {
784 Some(path) => {
785 match set_current_dir(path) {
786 Ok(()) => (),
787 Err(err) => {
788 eprint_error(&Error::Io(err));
789 return Some(1);
790 },
791 }
792 },
793 None => (),
794 }
795 let home = match create_home(home_dir, bin_path, lib_path, doc_path, false, f) {
796 Some(tmp_home) => tmp_home,
797 None => return Some(1),
798 };
799 let config = match PkgConfig::load_opt(home.pkg_config_file()) {
800 Ok(tmp_config) => tmp_config,
801 Err(err) => {
802 eprint_error(&err);
803 return Some(1);
804 },
805 };
806 let mut config_account: Option<String> = None;
807 let mut config_domain: Option<String> = None;
808 match config {
809 Some(config) => {
810 config_account = config.account.clone();
811 config_domain = config.domain.clone();
812 },
813 None => (),
814 }
815 let account = account.clone().or(config_account);
816 let domain = domain.clone().or(config_domain);
817 let name = match name {
818 Some(tmp_new_name) => tmp_new_name.clone(),
819 None => {
820 let dir = match current_dir() {
821 Ok(tmp_dir) => tmp_dir,
822 Err(err) => {
823 eprint_error(&Error::Io(err));
824 return Some(1);
825 },
826 };
827 let dir_name = match dir.file_name() {
828 Some(file_name) => {
829 match file_name.to_str() {
830 Some(tmp_dir_name) => tmp_dir_name,
831 None => {
832 eprintln!("directory name contains invalid UTF-8 character");
833 return Some(1);
834 },
835 }
836 },
837 None => {
838 eprintln!("no directory name");
839 return Some(1);
840 },
841 };
842 let mut tmp_name = match &account {
843 Some(account) => account.clone(),
844 None => {
845 eprintln!("no account");
846 return Some(1);
847 }
848 };
849 tmp_name.push('/');
850 tmp_name.push_str(dir_name);
851 tmp_name
852 },
853 };
854 let pkg_name = match parse_pkg_name(name.as_str()) {
855 Some(tmp_pkg_name) => tmp_pkg_name,
856 None => return Some(1),
857 };
858 let ss: Vec<&str> = pkg_name.name().split('/').collect();
859 let last_pkg_name_comp = match ss.last() {
860 Some(tmp_last_pkg_name_comp) => String::from(*tmp_last_pkg_name_comp),
861 None => {
862 eprintln!("no last package name component");
863 return Some(1);
864 },
865 };
866 let bin_name = last_pkg_name_comp.clone();
867 let lib_name = match &domain {
868 Some(domain) => {
869 let mut tmp_lib_name = domain.clone();
870 tmp_lib_name.push('/');
871 tmp_lib_name.push_str(last_pkg_name_comp.as_str());
872 tmp_lib_name
873 },
874 None => {
875 eprintln!("no domain");
876 return Some(1);
877 },
878 };
879 match res_init(&pkg_name, bin_name.as_str(), lib_name.as_str(), is_bin, is_lib, are_tests) {
880 Ok(()) => None,
881 Err(err) => {
882 eprint_error(&err);
883 Some(1)
884 },
885 }
886}
887
888fn create_and_change_dir<P: AsRef<Path>>(path: P) -> io::Result<PathBuf>
889{
890 let saved_current_dir = current_dir()?;
891 create_dir_all(path.as_ref())?;
892 match set_current_dir(path.as_ref()) {
893 Ok(()) => Ok(saved_current_dir),
894 Err(err) => {
895 remove_dir(path.as_ref())?;
896 return Err(err);
897 },
898 }
899}
900
901fn change_and_remove_dir<P: AsRef<Path>, Q: AsRef<Path>>(path: P, saved_current_dir: Q) -> io::Result<()>
902{
903 set_current_dir(saved_current_dir)?;
904 remove_dir(path)?;
905 Ok(())
906}
907
908pub fn new<F>(path: &str, name: &Option<String>, account: &Option<String>, domain: &Option<String>, is_bin: bool, is_lib: bool, are_tests: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
910 where F: FnOnce(&mut Home) -> bool
911{
912 let saved_current_dir = match create_and_change_dir(path) {
913 Ok(tmp_saved_current_dir) => tmp_saved_current_dir,
914 Err(err) => {
915 eprint_error(&Error::Io(err));
916 return Some(1);
917 },
918 };
919 match init(&None, name, account, domain, is_bin, is_lib, are_tests, home_dir, bin_path, lib_path, doc_path, f) {
920 None => None,
921 Some(exit_code) => {
922 match change_and_remove_dir(path, saved_current_dir) {
923 Ok(()) => (),
924 Err(err) => {
925 eprint_error(&Error::Io(err));
926 return Some(1);
927 },
928 }
929 Some(exit_code)
930 },
931 }
932}
933
934fn run_with_opt_name<F, G>(name: Option<&str>, args: Vec<String>, is_ctrl_c_intr_checker: bool, are_plotter_windows: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F, g: G) -> Option<i32>
935 where F: FnOnce(&mut Home) -> bool,
936 G: FnOnce(&mut ModNode<Value, ()>)
937{
938 let mut home = match create_home(home_dir, bin_path, lib_path, doc_path, true, f) {
939 Some(tmp_home) => tmp_home,
940 None => return Some(1),
941 };
942 match home.add_dirs_to_bin_path(&[String::from("bin")]) {
943 Ok(()) => (),
944 Err(err) => {
945 eprintln!("{}", err);
946 return Some(1);
947 },
948 }
949 match home.add_dirs_to_lib_path(&[String::from("lib")]) {
950 Ok(()) => (),
951 Err(err) => {
952 eprintln!("{}", err);
953 return Some(1);
954 },
955 }
956 match PkgManager::manifest() {
957 Ok(_) => (),
958 Err(err) => {
959 eprint_error(&err);
960 return None;
961 },
962 }
963 match initialize_backend(home.backend_config_file()) {
964 Ok(()) => (),
965 Err(err) => {
966 eprint_error(&err);
967 return Some(1);
968 },
969 }
970 let script_file = match &name {
971 Some(name) => {
972 let mut tmp_script_file = String::from("bin");
973 tmp_script_file.push(path::MAIN_SEPARATOR);
974 tmp_script_file.push_str(name);
975 Some(tmp_script_file)
976 },
977 None => None,
978 };
979 let exit_code = {
980 let mut root_mod: ModNode<Value, ()> = ModNode::new(());
981 g(&mut root_mod);
982 let root_mod_arc = Arc::new(RwLock::new(root_mod));
983 main_loop(script_file, args, PathBuf::from(home.history_file()), root_mod_arc, OsString::from(home.lib_path()), OsString::from(home.doc_path()), is_ctrl_c_intr_checker, are_plotter_windows)
984 };
985 match finalize_backend() {
986 Ok(()) => (),
987 Err(err) => {
988 eprint_error(&err);
989 return Some(1);
990 },
991 }
992 exit_code
993}
994
995pub fn run<F, G>(name: &str, args: Vec<String>, is_ctrl_c_intr_checker: bool, are_plotter_windows: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F, g: G) -> Option<i32>
997 where F: FnOnce(&mut Home) -> bool,
998 G: FnOnce(&mut ModNode<Value, ()>)
999{ run_with_opt_name(Some(name), args, is_ctrl_c_intr_checker, are_plotter_windows, home_dir, bin_path, lib_path, doc_path, f, g) }
1000
1001pub fn console<F, G>(is_ctrl_c_intr_checker: bool, are_plotter_windows: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F, g: G) -> Option<i32>
1003 where F: FnOnce(&mut Home) -> bool,
1004 G: FnOnce(&mut ModNode<Value, ()>)
1005{ run_with_opt_name(None, Vec::new(), is_ctrl_c_intr_checker, are_plotter_windows, home_dir, bin_path, lib_path, doc_path, f, g) }
1006
1007fn res_doc(pkg_manager: &PkgManager) -> Result<()>
1008{
1009 pkg_manager.check_last_op(true)?;
1010 pkg_manager.generate_doc()?;
1011 Ok(())
1012}
1013
1014pub fn doc<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
1016 where F: FnOnce(&mut Home) -> bool
1017{
1018 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) {
1019 Some(tmp_pkg_manager) => tmp_pkg_manager,
1020 None => return Some(1),
1021 };
1022 match res_doc(&pkg_manager) {
1023 Ok(()) => None,
1024 Err(err) => {
1025 pkg_manager.printer().print_lf_for_error();
1026 eprint_error(&err);
1027 Some(1)
1028 },
1029 }
1030}
1031
1032#[derive(Clone, Debug)]
1033enum TestName
1034{
1035 Test(Vec<String>, String),
1036 TestSuite(Vec<String>),
1037}
1038
1039fn res_test(tester: &mut Tester, test_name: &Option<TestName>, are_success_outputs: bool) -> Result<()>
1040{
1041 tester.load()?;
1042 match test_name {
1043 Some(TestName::Test(idents, ident)) => tester.run_test(idents, ident)?,
1044 Some(TestName::TestSuite(idents)) => tester.run_tests_in_test_suite(idents)?,
1045 None => tester.run_all_tests()?,
1046 }
1047 tester.print_empty_line();
1048 if are_success_outputs {
1049 tester.print_successes()?;
1050 }
1051 tester.print_failures()?;
1052 tester.print_test_counts();
1053 Ok(())
1054}
1055
1056pub fn test<F, G>(name: &Option<String>, is_test_suite: bool, are_success_outputs: bool, are_output_cursors: bool, home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F, g: G) -> Option<i32>
1058 where F: FnOnce(&mut Home) -> bool,
1059 G: FnOnce(&mut ModNode<Value, ()>)
1060{
1061 let test_name = match name {
1062 Some(name) => {
1063 if is_test_suite {
1064 Some(TestName::TestSuite(parse_idents(name.as_str())))
1065 } else {
1066 match parse_idents_and_ident(name.as_str()) {
1067 Some((idents, ident)) => Some(TestName::Test(idents, ident)),
1068 None => return Some(1),
1069 }
1070 }
1071 },
1072 None => None,
1073 };
1074 let mut home = match create_home(home_dir, bin_path, lib_path, doc_path, true, f) {
1075 Some(tmp_home) => tmp_home,
1076 None => return Some(1),
1077 };
1078 match home.add_dirs_to_bin_path(&[String::from("bin")]) {
1079 Ok(()) => (),
1080 Err(err) => {
1081 eprintln!("{}", err);
1082 return Some(1);
1083 },
1084 }
1085 match home.add_dirs_to_lib_path(&[String::from("lib")]) {
1086 Ok(()) => (),
1087 Err(err) => {
1088 eprintln!("{}", err);
1089 return Some(1);
1090 },
1091 }
1092 match PkgManager::manifest() {
1093 Ok(_) => (),
1094 Err(err) => {
1095 eprint_error(&err);
1096 return None;
1097 },
1098 }
1099 match initialize_backend(home.backend_config_file()) {
1100 Ok(()) => (),
1101 Err(err) => {
1102 eprint_error(&err);
1103 return Some(1);
1104 },
1105 }
1106 let exit_code = {
1107 let mut root_mod: ModNode<Value, ()> = ModNode::new(());
1108 g(&mut root_mod);
1109 let root_mod_arc = Arc::new(RwLock::new(root_mod));
1110 let mut tester = Tester::new(root_mod_arc, OsString::from(home.lib_path()), OsString::from(home.doc_path()), Arc::new(tester::StdPrinter::new()), are_output_cursors, are_output_cursors);
1111 match res_test(&mut tester, &test_name, are_success_outputs) {
1112 Ok(()) => None,
1113 Err(err) => {
1114 tester.printer().print_lf_for_error();
1115 eprint_error_with_stack_trace(&err, tester.stack_trace());
1116 Some(1)
1117 },
1118 }
1119 };
1120 match finalize_backend() {
1121 Ok(()) => (),
1122 Err(err) => {
1123 eprint_error(&err);
1124 return Some(1);
1125 },
1126 }
1127 exit_code
1128}
1129
1130fn res_clean_test() -> Result<()>
1131{
1132 PkgManager::manifest()?;
1133 let mut work_test_dir = PathBuf::from("work");
1134 work_test_dir.push("test");
1135 match io_res_clean_dir(work_test_dir, "Cleaning test ...") {
1136 Ok(()) => Ok(()),
1137 Err(err) => {
1138 println!("");
1139 Err(Error::Io(err))
1140 },
1141 }
1142}
1143
1144pub fn clean_test<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, f: F) -> Option<i32>
1146 where F: FnOnce(&mut Home) -> bool
1147{
1148 match create_home(home_dir, bin_path, lib_path, doc_path, true, f) {
1149 Some(_) => (),
1150 None => return Some(1),
1151 }
1152 match res_clean_test() {
1153 Ok(()) => None,
1154 Err(err) => {
1155 eprint_error(&err);
1156 Some(1)
1157 },
1158 }
1159}
1160
1161fn res_std_doc(pkg_manager: &PkgManager, are_deps: bool) -> Result<()>
1162{
1163 pkg_manager.check_last_op(are_deps)?;
1164 pkg_manager.generate_std_doc()?;
1165 Ok(())
1166}
1167
1168fn std_doc_with_dep_flag<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, are_deps: bool, f: F) -> Option<i32>
1169 where F: FnOnce(&mut Home) -> bool
1170{
1171 let pkg_manager = match create_pkg_manager(home_dir, bin_path, lib_path, doc_path, src_factories, are_deps, f) {
1172 Some(tmp_pkg_manager) => tmp_pkg_manager,
1173 None => return Some(1),
1174 };
1175 match res_std_doc(&pkg_manager, are_deps) {
1176 Ok(()) => None,
1177 Err(err) => {
1178 pkg_manager.printer().print_lf_for_error();
1179 eprint_error(&err);
1180 Some(1)
1181 },
1182 }
1183}
1184
1185pub fn std_doc<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
1187 where F: FnOnce(&mut Home) -> bool
1188{ std_doc_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, false, f) }
1189
1190pub fn std_doc_deps<F>(home_dir: &Option<String>, bin_path: &Option<String>, lib_path: &Option<String>, doc_path: &Option<String>, src_factories: Vec<Arc<dyn SourceCreate + Send + Sync>>, f: F) -> Option<i32>
1192 where F: FnOnce(&mut Home) -> bool
1193{ std_doc_with_dep_flag(home_dir, bin_path, lib_path, doc_path, src_factories, true, f) }