1
1
use tracing:: debug;
2
2
3
3
use crate :: commands:: pip:: loggers:: { InstallLogger , ResolveLogger } ;
4
+ use crate :: commands:: project:: install_target:: InstallTarget ;
4
5
use crate :: commands:: project:: {
5
6
resolve_environment, sync_environment, EnvironmentSpecification , ProjectError ,
6
7
} ;
@@ -9,10 +10,13 @@ use crate::settings::ResolverInstallerSettings;
9
10
use uv_cache:: { Cache , CacheBucket } ;
10
11
use uv_cache_key:: { cache_digest, hash_digest} ;
11
12
use uv_client:: Connectivity ;
12
- use uv_configuration:: { Concurrency , PreviewMode , TrustedHost } ;
13
+ use uv_configuration:: {
14
+ Concurrency , DevGroupsManifest , ExtrasSpecification , InstallOptions , PreviewMode , TrustedHost ,
15
+ } ;
13
16
use uv_dispatch:: SharedState ;
14
17
use uv_distribution_types:: { Name , Resolution } ;
15
18
use uv_python:: { Interpreter , PythonEnvironment } ;
19
+ use uv_resolver:: Installable ;
16
20
17
21
/// A [`PythonEnvironment`] stored in the cache.
18
22
#[ derive( Debug ) ]
@@ -25,9 +29,8 @@ impl From<CachedEnvironment> for PythonEnvironment {
25
29
}
26
30
27
31
impl CachedEnvironment {
28
- /// Get or create an [`CachedEnvironment`] based on a given set of requirements and a base
29
- /// interpreter.
30
- pub ( crate ) async fn get_or_create (
32
+ /// Get or create an [`CachedEnvironment`] based on a given set of requirements.
33
+ pub ( crate ) async fn from_spec (
31
34
spec : EnvironmentSpecification < ' _ > ,
32
35
interpreter : Interpreter ,
33
36
settings : & ResolverInstallerSettings ,
@@ -43,21 +46,7 @@ impl CachedEnvironment {
43
46
printer : Printer ,
44
47
preview : PreviewMode ,
45
48
) -> Result < Self , ProjectError > {
46
- // When caching, always use the base interpreter, rather than that of the virtual
47
- // environment.
48
- let interpreter = if let Some ( interpreter) = interpreter. to_base_interpreter ( cache) ? {
49
- debug ! (
50
- "Caching via base interpreter: `{}`" ,
51
- interpreter. sys_executable( ) . display( )
52
- ) ;
53
- interpreter
54
- } else {
55
- debug ! (
56
- "Caching via interpreter: `{}`" ,
57
- interpreter. sys_executable( ) . display( )
58
- ) ;
59
- interpreter
60
- } ;
49
+ let interpreter = Self :: base_interpreter ( interpreter, cache) ?;
61
50
62
51
// Resolve the requirements with the interpreter.
63
52
let resolution = Resolution :: from (
@@ -78,6 +67,93 @@ impl CachedEnvironment {
78
67
. await ?,
79
68
) ;
80
69
70
+ Self :: from_resolution (
71
+ resolution,
72
+ interpreter,
73
+ settings,
74
+ state,
75
+ install,
76
+ installer_metadata,
77
+ connectivity,
78
+ concurrency,
79
+ native_tls,
80
+ allow_insecure_host,
81
+ cache,
82
+ printer,
83
+ preview,
84
+ )
85
+ . await
86
+ }
87
+
88
+ /// Get or create an [`CachedEnvironment`] based on a given [`InstallTarget`].
89
+ pub ( crate ) async fn from_lock (
90
+ target : InstallTarget < ' _ > ,
91
+ extras : & ExtrasSpecification ,
92
+ dev : & DevGroupsManifest ,
93
+ install_options : InstallOptions ,
94
+ settings : & ResolverInstallerSettings ,
95
+ interpreter : Interpreter ,
96
+ state : & SharedState ,
97
+ install : Box < dyn InstallLogger > ,
98
+ installer_metadata : bool ,
99
+ connectivity : Connectivity ,
100
+ concurrency : Concurrency ,
101
+ native_tls : bool ,
102
+ allow_insecure_host : & [ TrustedHost ] ,
103
+ cache : & Cache ,
104
+ printer : Printer ,
105
+ preview : PreviewMode ,
106
+ ) -> Result < Self , ProjectError > {
107
+ let interpreter = Self :: base_interpreter ( interpreter, cache) ?;
108
+
109
+ // Determine the tags, markers, and interpreter to use for resolution.
110
+ let tags = interpreter. tags ( ) ?;
111
+ let marker_env = interpreter. resolver_marker_environment ( ) ;
112
+
113
+ // Read the lockfile.
114
+ let resolution = target. to_resolution (
115
+ & marker_env,
116
+ tags,
117
+ extras,
118
+ dev,
119
+ & settings. build_options ,
120
+ & install_options,
121
+ ) ?;
122
+
123
+ Self :: from_resolution (
124
+ resolution,
125
+ interpreter,
126
+ settings,
127
+ state,
128
+ install,
129
+ installer_metadata,
130
+ connectivity,
131
+ concurrency,
132
+ native_tls,
133
+ allow_insecure_host,
134
+ cache,
135
+ printer,
136
+ preview,
137
+ )
138
+ . await
139
+ }
140
+
141
+ /// Get or create an [`CachedEnvironment`] based on a given [`Resolution`].
142
+ pub ( crate ) async fn from_resolution (
143
+ resolution : Resolution ,
144
+ interpreter : Interpreter ,
145
+ settings : & ResolverInstallerSettings ,
146
+ state : & SharedState ,
147
+ install : Box < dyn InstallLogger > ,
148
+ installer_metadata : bool ,
149
+ connectivity : Connectivity ,
150
+ concurrency : Concurrency ,
151
+ native_tls : bool ,
152
+ allow_insecure_host : & [ TrustedHost ] ,
153
+ cache : & Cache ,
154
+ printer : Printer ,
155
+ preview : PreviewMode ,
156
+ ) -> Result < Self , ProjectError > {
81
157
// Hash the resolution by hashing the generated lockfile.
82
158
// TODO(charlie): If the resolution contains any mutable metadata (like a path or URL
83
159
// dependency), skip this step.
@@ -144,4 +220,28 @@ impl CachedEnvironment {
144
220
pub ( crate ) fn into_interpreter ( self ) -> Interpreter {
145
221
self . 0 . into_interpreter ( )
146
222
}
223
+
224
+ /// Return the [`Interpreter`] to use for the cached environment, based on a given
225
+ /// [`Interpreter`].
226
+ ///
227
+ /// When caching, always use the base interpreter, rather than that of the virtual
228
+ /// environment.
229
+ fn base_interpreter (
230
+ interpreter : Interpreter ,
231
+ cache : & Cache ,
232
+ ) -> Result < Interpreter , uv_python:: Error > {
233
+ if let Some ( interpreter) = interpreter. to_base_interpreter ( cache) ? {
234
+ debug ! (
235
+ "Caching via base interpreter: `{}`" ,
236
+ interpreter. sys_executable( ) . display( )
237
+ ) ;
238
+ Ok ( interpreter)
239
+ } else {
240
+ debug ! (
241
+ "Caching via interpreter: `{}`" ,
242
+ interpreter. sys_executable( ) . display( )
243
+ ) ;
244
+ Ok ( interpreter)
245
+ }
246
+ }
147
247
}
0 commit comments