@@ -54,6 +54,23 @@ impl DependencyManagerConfig {
54
54
}
55
55
}
56
56
57
+ pub struct Resolved {
58
+ pub manifest : Manifest ,
59
+ pub versions_changed : bool ,
60
+ }
61
+
62
+ impl Resolved {
63
+ /// Create a `Resolved`, comparing the old and new versions of the manifest to work out
64
+ /// if resolution resulted in any changes.
65
+ pub fn with_updates ( old : & Manifest , new : Manifest ) -> Self {
66
+ let versions_changed = old. packages != new. packages ;
67
+ Self {
68
+ manifest : new,
69
+ versions_changed,
70
+ }
71
+ }
72
+ }
73
+
57
74
pub struct DependencyManager < Telem , P > {
58
75
runtime : tokio:: runtime:: Handle ,
59
76
package_fetcher : P ,
@@ -68,50 +85,61 @@ where
68
85
P : dependency:: PackageFetcher ,
69
86
Telem : Telemetry ,
70
87
{
71
- pub fn get_manifest (
88
+ /// Resolve the dependency versions used by a package.
89
+ ///
90
+ /// If the `use_manifest` configuration was set to `false` then it'll always resolve all the
91
+ /// versions, even if there are already versions locked in the manifest.
92
+ pub fn resolve_versions (
72
93
& self ,
73
94
paths : & ProjectPaths ,
74
95
config : & PackageConfig ,
75
96
packages_to_update : Vec < EcoString > ,
76
- ) -> Result < ( bool , Manifest ) > {
77
- // If there's no manifest (or we have been asked not to use it) then resolve
78
- // the versions anew
79
- let should_resolve = match self . use_manifest {
80
- _ if !paths. manifest ( ) . exists ( ) => {
81
- tracing:: debug!( "manifest_not_present" ) ;
82
- true
83
- }
84
- UseManifest :: No => {
85
- tracing:: debug!( "ignoring_manifest" ) ;
86
- true
97
+ ) -> Result < Resolved > {
98
+ // If there's no manifest then the only thing we can do is attempt to update the versions.
99
+ if !paths. manifest ( ) . exists ( ) {
100
+ tracing:: debug!( "manifest_not_present" ) ;
101
+ let manifest = self . perform_version_resolution ( paths, config, None , Vec :: new ( ) ) ?;
102
+ return Ok ( Resolved {
103
+ manifest,
104
+ versions_changed : true ,
105
+ } ) ;
106
+ }
107
+
108
+ let existing_manifest = read_manifest_from_disc ( paths) ?;
109
+
110
+ // If we have been asked not to use the manifest then
111
+ let manifest_for_resolver = match self . use_manifest {
112
+ UseManifest :: No => None ,
113
+ UseManifest :: Yes => {
114
+ // If the manifest is to be used and the requirements have not changed then there's
115
+ // no point in performing resolution, it'll always result in the same versions
116
+ // already specified in the manifest.
117
+ if packages_to_update. is_empty ( )
118
+ && is_same_requirements (
119
+ & existing_manifest. requirements ,
120
+ & config. all_direct_dependencies ( ) ?,
121
+ paths. root ( ) ,
122
+ ) ?
123
+ {
124
+ return Ok ( Resolved {
125
+ manifest : existing_manifest,
126
+ versions_changed : false ,
127
+ } ) ;
128
+ }
129
+
130
+ // Otherwise, use the manifest to inform resolution.
131
+ Some ( & existing_manifest)
87
132
}
88
- UseManifest :: Yes => false ,
89
133
} ;
90
134
91
- if should_resolve {
92
- let manifest = self . resolve_versions ( paths, config, None , Vec :: new ( ) ) ?;
93
- return Ok ( ( true , manifest) ) ;
94
- }
95
-
96
- let manifest = read_manifest_from_disc ( paths) ?;
97
-
98
- // If there are no requested updates, and the config is unchanged
99
- // since the manifest was written then it is up to date so we can return it unmodified.
100
- if packages_to_update. is_empty ( )
101
- && is_same_requirements (
102
- & manifest. requirements ,
103
- & config. all_direct_dependencies ( ) ?,
104
- paths. root ( ) ,
105
- ) ?
106
- {
107
- tracing:: debug!( "manifest_up_to_date" ) ;
108
- Ok ( ( false , manifest) )
109
- } else {
110
- tracing:: debug!( "manifest_outdated" ) ;
111
- let manifest =
112
- self . resolve_versions ( paths, config, Some ( & manifest) , packages_to_update) ?;
113
- Ok ( ( true , manifest) )
114
- }
135
+ tracing:: debug!( "manifest_outdated" ) ;
136
+ let new_manifest = self . perform_version_resolution (
137
+ paths,
138
+ config,
139
+ manifest_for_resolver,
140
+ packages_to_update,
141
+ ) ?;
142
+ Ok ( Resolved :: with_updates ( & existing_manifest, new_manifest) )
115
143
}
116
144
117
145
pub fn download (
@@ -148,7 +176,10 @@ where
148
176
}
149
177
150
178
// Determine what versions we need
151
- let ( manifest_updated, manifest) = self . get_manifest ( paths, & config, packages_to_update) ?;
179
+ let Resolved {
180
+ manifest,
181
+ versions_changed : manifest_updated,
182
+ } = self . resolve_versions ( paths, & config, packages_to_update) ?;
152
183
let local = LocalPackages :: read_from_disc ( paths) ?;
153
184
154
185
// Remove any packages that are no longer required due to gleam.toml changes
@@ -186,7 +217,7 @@ where
186
217
Ok ( manifest)
187
218
}
188
219
189
- fn resolve_versions (
220
+ fn perform_version_resolution (
190
221
& self ,
191
222
project_paths : & ProjectPaths ,
192
223
config : & PackageConfig ,
0 commit comments