1
- use :: std:: fs:: { copy, create_dir_all} ;
1
+ use :: std:: fs:: { copy, create_dir_all, write } ;
2
2
use :: std:: path:: { Path , PathBuf } ;
3
3
4
4
use duct:: cmd;
5
+ use rayon:: prelude:: * ;
5
6
use tauri:: path:: BaseDirectory ;
6
7
use tauri:: Manager ;
8
+ use tempfile:: Builder ;
9
+ use yaml_rust2:: Yaml ;
7
10
11
+ use crate :: interpreter:: extract;
8
12
use crate :: interpreter:: shasum;
9
13
10
14
#[ cfg( desktop) ]
11
- pub async fn pip_install_if_needed (
15
+ fn pip_install_if_needed_with_hash (
12
16
cache_path : & Path ,
13
17
requirements_path : & Path ,
18
+ hash : String ,
19
+ force : bool ,
14
20
) -> Result < PathBuf , tauri:: Error > {
15
21
create_dir_all ( & cache_path) ?;
16
22
17
- let hash = shasum:: sha256sum ( & requirements_path) ?;
18
23
let venv_path = cache_path. join ( "venvs" ) . join ( hash) ;
19
24
let bin_path = venv_path. join ( if cfg ! ( windows) { "Scripts" } else { "bin" } ) ;
20
25
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.
21
30
if !venv_path. exists ( ) {
22
31
println ! ( "Creating virtual environment..." ) ;
23
32
let python = if cfg ! ( target_os = "macos" ) {
@@ -27,18 +36,65 @@ pub async fn pip_install_if_needed(
27
36
} ;
28
37
cmd ! ( python, "-mvenv" , & venv_path) . run ( ) ?;
29
38
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
+ }
31
46
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 ( ) ?;
34
49
}
35
50
36
51
Ok ( bin_path. to_path_buf ( ) )
37
52
}
38
53
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
+
39
95
#[ cfg( desktop) ]
40
96
pub async fn pip_install_internal_if_needed (
41
- app_handle : tauri:: AppHandle ,
97
+ app_handle : & tauri:: AppHandle ,
42
98
requirements : & str ,
43
99
) -> Result < PathBuf , tauri:: Error > {
44
100
// the interpreter requirements.txt
@@ -48,5 +104,5 @@ pub async fn pip_install_internal_if_needed(
48
104
49
105
let cache_path = app_handle. path ( ) . cache_dir ( ) ?. join ( "pdl" ) ;
50
106
51
- pip_install_if_needed ( & cache_path, & requirements_path) . await
107
+ pip_install_if_needed ( & cache_path, & requirements_path)
52
108
}
0 commit comments