@@ -7,7 +7,7 @@ use uv_configuration::Upgrade;
7
7
use uv_fs:: CWD ;
8
8
use uv_git:: ResolvedRepositoryReference ;
9
9
use uv_requirements_txt:: RequirementsTxt ;
10
- use uv_resolver:: { Lock , LockError , Preference , PreferenceError } ;
10
+ use uv_resolver:: { Lock , LockError , Preference , PreferenceError , PylockToml , PylockTomlError } ;
11
11
12
12
#[ derive( Debug , Default ) ]
13
13
pub struct LockedRequirements {
@@ -17,21 +17,26 @@ pub struct LockedRequirements {
17
17
pub git : Vec < ResolvedRepositoryReference > ,
18
18
}
19
19
20
+ impl LockedRequirements {
21
+ /// Create a [`LockedRequirements`] from a list of preferences.
22
+ pub fn from_preferences ( preferences : Vec < Preference > ) -> Self {
23
+ Self {
24
+ preferences,
25
+ ..LockedRequirements :: default ( )
26
+ }
27
+ }
28
+ }
29
+
20
30
/// Load the preferred requirements from an existing `requirements.txt`, applying the upgrade strategy.
21
31
pub async fn read_requirements_txt (
22
- output_file : Option < & Path > ,
32
+ output_file : & Path ,
23
33
upgrade : & Upgrade ,
24
34
) -> Result < Vec < Preference > > {
25
35
// As an optimization, skip reading the lockfile is we're upgrading all packages anyway.
26
36
if upgrade. is_all ( ) {
27
37
return Ok ( Vec :: new ( ) ) ;
28
38
}
29
39
30
- // If the lockfile doesn't exist, don't respect any pinned versions.
31
- let Some ( output_file) = output_file. filter ( |path| path. exists ( ) ) else {
32
- return Ok ( Vec :: new ( ) ) ;
33
- } ;
34
-
35
40
// Parse the requirements from the lockfile.
36
41
let requirements_txt = RequirementsTxt :: parse (
37
42
output_file,
@@ -95,3 +100,40 @@ pub fn read_lock_requirements(
95
100
96
101
Ok ( LockedRequirements { preferences, git } )
97
102
}
103
+
104
+ /// Load the preferred requirements from an existing `pylock.toml` file, applying the upgrade strategy.
105
+ pub async fn read_pylock_toml_requirements (
106
+ output_file : & Path ,
107
+ upgrade : & Upgrade ,
108
+ ) -> Result < LockedRequirements , PylockTomlError > {
109
+ // As an optimization, skip iterating over the lockfile is we're upgrading all packages anyway.
110
+ if upgrade. is_all ( ) {
111
+ return Ok ( LockedRequirements :: default ( ) ) ;
112
+ }
113
+
114
+ // Read the `pylock.toml` from disk, and deserialize it from TOML.
115
+ let content = fs_err:: tokio:: read_to_string ( & output_file) . await ?;
116
+ let lock = toml:: from_str :: < PylockToml > ( & content) ?;
117
+
118
+ let mut preferences = Vec :: new ( ) ;
119
+ let mut git = Vec :: new ( ) ;
120
+
121
+ for package in & lock. packages {
122
+ // Skip the distribution if it's not included in the upgrade strategy.
123
+ if upgrade. contains ( & package. name ) {
124
+ continue ;
125
+ }
126
+
127
+ // Map each entry in the lockfile to a preference.
128
+ if let Some ( preference) = Preference :: from_pylock_toml ( package) ? {
129
+ preferences. push ( preference) ;
130
+ }
131
+
132
+ // Map each entry in the lockfile to a Git SHA.
133
+ if let Some ( git_ref) = package. as_git_ref ( ) {
134
+ git. push ( git_ref) ;
135
+ }
136
+ }
137
+
138
+ Ok ( LockedRequirements { preferences, git } )
139
+ }
0 commit comments