1- use :: std:: fs:: { copy, create_dir_all} ;
1+ use :: std:: fs:: { copy, create_dir_all, write } ;
22use :: std:: path:: { Path , PathBuf } ;
33
44use duct:: cmd;
5+ use rayon:: prelude:: * ;
56use tauri:: path:: BaseDirectory ;
67use tauri:: Manager ;
8+ use tempfile:: Builder ;
9+ use yaml_rust2:: Yaml ;
710
11+ use crate :: interpreter:: extract;
812use crate :: interpreter:: shasum;
913
1014#[ cfg( desktop) ]
11- pub async fn pip_install_if_needed (
15+ fn pip_install_if_needed_with_hash (
1216 cache_path : & Path ,
1317 requirements_path : & Path ,
18+ hash : String ,
19+ force : bool ,
1420) -> Result < PathBuf , tauri:: Error > {
1521 create_dir_all ( & cache_path) ?;
1622
17- let hash = shasum:: sha256sum ( & requirements_path) ?;
1823 let venv_path = cache_path. join ( "venvs" ) . join ( hash) ;
1924 let bin_path = venv_path. join ( if cfg ! ( windows) { "Scripts" } else { "bin" } ) ;
2025
26+ // re: force, this is part of the short-term hack to install all
27+ // code block dependencies in the main interpreter venv. Once we
28+ // figure out how to support a separate venv for each code block
29+ // (that needs it), we can undo this hack.
2130 if !venv_path. exists ( ) {
2231 println ! ( "Creating virtual environment..." ) ;
2332 let python = if cfg ! ( target_os = "macos" ) {
@@ -27,18 +36,65 @@ pub async fn pip_install_if_needed(
2736 } ;
2837 cmd ! ( python, "-mvenv" , & venv_path) . run ( ) ?;
2938
30- cmd ! ( bin_path. join( "pip" ) , "install" , "-r" , & requirements_path, ) . run ( ) ?;
39+ if !force {
40+ cmd ! ( bin_path. join( "pip" ) , "install" , "-r" , & requirements_path) . run ( ) ?;
41+
42+ let cached_requirements_path = venv_path. join ( "requirements.txt" ) ;
43+ copy ( requirements_path, cached_requirements_path) ?;
44+ }
45+ }
3146
32- let cached_requirements_path = venv_path . join ( "requirements.txt" ) ;
33- copy ( requirements_path , cached_requirements_path ) ?;
47+ if force {
48+ cmd ! ( bin_path . join ( "pip" ) , "install" , "-r" , & requirements_path ) . run ( ) ?;
3449 }
3550
3651 Ok ( bin_path. to_path_buf ( ) )
3752}
3853
54+ #[ cfg( desktop) ]
55+ fn pip_install_if_needed (
56+ cache_path : & Path ,
57+ requirements_path : & Path ,
58+ ) -> Result < PathBuf , tauri:: Error > {
59+ let hash = shasum:: sha256sum ( & requirements_path) ?;
60+ pip_install_if_needed_with_hash ( cache_path, requirements_path, hash, false )
61+ }
62+
63+ #[ cfg( desktop) ]
64+ pub async fn pip_install_code_blocks_if_needed (
65+ app_handle : & tauri:: AppHandle ,
66+ program : & Yaml ,
67+ ) -> Result < ( ) , tauri:: Error > {
68+ let cache_path = app_handle. path ( ) . cache_dir ( ) ?. join ( "pdl" ) ;
69+
70+ // for now, install the requirements in the main interpreter venv
71+ let requirements_path = app_handle
72+ . path ( )
73+ . resolve ( "interpreter/requirements.txt" , BaseDirectory :: Resource ) ?;
74+
75+ extract:: extract_requirements ( program)
76+ . into_par_iter ( )
77+ . try_for_each ( |req| -> Result < ( ) , tauri:: Error > {
78+ let req_path = Builder :: new ( )
79+ . prefix ( "pdl-requirements-" )
80+ . suffix ( ".txt" )
81+ . tempfile ( ) ?;
82+ // This is part of the "force" hack described above, where
83+ // we force the code block dependencies to be installed in
84+ // the main interpreter venv.
85+ let hash = shasum:: sha256sum ( & requirements_path) ?;
86+ write ( & req_path, req) ?;
87+ pip_install_if_needed_with_hash ( & cache_path, & req_path. path ( ) , hash, true ) ?;
88+ Ok ( ( ) )
89+ } )
90+ . expect ( "code block requirements installed" ) ;
91+
92+ Ok ( ( ) )
93+ }
94+
3995#[ cfg( desktop) ]
4096pub async fn pip_install_internal_if_needed (
41- app_handle : tauri:: AppHandle ,
97+ app_handle : & tauri:: AppHandle ,
4298 requirements : & str ,
4399) -> Result < PathBuf , tauri:: Error > {
44100 // the interpreter requirements.txt
@@ -48,5 +104,5 @@ pub async fn pip_install_internal_if_needed(
48104
49105 let cache_path = app_handle. path ( ) . cache_dir ( ) ?. join ( "pdl" ) ;
50106
51- pip_install_if_needed ( & cache_path, & requirements_path) . await
107+ pip_install_if_needed ( & cache_path, & requirements_path)
52108}
0 commit comments