@@ -53,7 +53,11 @@ Dev, build, and all target dependencies will also be upgraded. Only dependencies
53
53
supported. Git/path dependencies will be ignored.
54
54
55
55
All packages in the workspace will be upgraded if the `--all` flag is supplied. The `--all` flag may
56
- be supplied in the presence of a virtual manifest."
56
+ be supplied in the presence of a virtual manifest.
57
+
58
+ If the '--to-lockfile' flag is supplied, all dependencies will be upraged to the currently locked
59
+ version as recorded in the local lock file. The local lock file must be present and up to date if
60
+ this flag is passed."
57
61
) ]
58
62
Upgrade ( Args ) ,
59
63
}
@@ -82,6 +86,10 @@ struct Args {
82
86
/// Run without accessing the network
83
87
#[ structopt( long = "offline" ) ]
84
88
pub offline : bool ,
89
+
90
+ /// Upgrade all packages to the version in the lockfile.
91
+ #[ structopt( long = "to-lockfile" , conflicts_with = "dependency" ) ]
92
+ pub to_lockfile : bool ,
85
93
}
86
94
87
95
/// A collection of manifests.
@@ -140,9 +148,7 @@ impl Manifests {
140
148
Ok ( Manifests ( vec ! [ ( manifest, package. to_owned( ) ) ] ) )
141
149
}
142
150
143
- /// Get the the combined set of dependencies to upgrade. If the user has specified
144
- /// per-dependency desired versions, extract those here.
145
- fn get_dependencies ( & self , only_update : Vec < String > ) -> Result < DesiredUpgrades > {
151
+ fn get_all_requested_dependencies ( & self ) -> Vec < cargo_metadata:: Dependency > {
146
152
/// Helper function to check whether a `cargo_metadata::Dependency` is a version dependency.
147
153
fn is_version_dep ( dependency : & cargo_metadata:: Dependency ) -> bool {
148
154
match dependency. source {
@@ -153,13 +159,69 @@ impl Manifests {
153
159
}
154
160
}
155
161
162
+ self . 0
163
+ . iter ( )
164
+ . flat_map ( |& ( _, ref package) | package. dependencies . clone ( ) )
165
+ . filter ( is_version_dep)
166
+ . collect ( )
167
+ }
168
+
169
+ fn get_locked_dependencies ( & self ) -> Result < Vec < cargo_metadata:: Package > > {
170
+ Ok ( self
171
+ . 0
172
+ . iter ( )
173
+ . map ( |( manifest, _package) | {
174
+ let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
175
+ cmd. manifest_path ( manifest. path . clone ( ) ) ;
176
+ cmd. other_options ( vec ! [ "--locked" . to_string( ) ] ) ;
177
+
178
+ let result = cmd
179
+ . exec ( )
180
+ . map_err ( |e| Error :: from ( e. compat ( ) ) . chain_err ( || "Invalid manifest" ) ) ?;
181
+
182
+ Ok ( result
183
+ . packages
184
+ . into_iter ( )
185
+ . filter ( |p| p. source . is_some ( ) )
186
+ . collect :: < Vec < _ > > ( ) )
187
+ } )
188
+ . collect :: < Result < Vec < _ > > > ( ) ?
189
+ . into_iter ( )
190
+ . flatten ( )
191
+ . collect ( ) )
192
+ }
193
+
194
+ /// Get the the combined set of dependencies to upgrade. If the user has specified
195
+ /// per-dependency desired versions, extract those here.
196
+ fn get_dependencies (
197
+ & self ,
198
+ only_update : Vec < String > ,
199
+ to_lockfile : bool ,
200
+ ) -> Result < DesiredUpgrades > {
201
+ if to_lockfile {
202
+ let locked = self . get_locked_dependencies ( ) ?;
203
+ return Ok ( DesiredUpgrades (
204
+ self . get_all_requested_dependencies ( )
205
+ . into_iter ( )
206
+ . filter_map ( |d| {
207
+ for p in & locked {
208
+ // The requested depenency may be present in the lock file with different versions,
209
+ // but only one will be semver-compatible with requested version.
210
+ if d. name == p. name && d. req . matches ( & p. version ) {
211
+ return Some ( ( d. name , Some ( p. version . to_string ( ) ) ) ) ;
212
+ }
213
+ }
214
+ return None ;
215
+ } )
216
+ . collect ( ) ,
217
+ ) ) ;
218
+ }
219
+
156
220
Ok ( DesiredUpgrades ( if only_update. is_empty ( ) {
157
221
// User hasn't asked for any specific dependencies to be upgraded, so upgrade all the
158
222
// dependencies.
159
- self . 0
160
- . iter ( )
161
- . flat_map ( |& ( _, ref package) | package. dependencies . clone ( ) )
162
- . filter ( is_version_dep)
223
+ self . get_all_requested_dependencies ( )
224
+ . into_iter ( )
163
225
. map ( |dependency| ( dependency. name , None ) )
164
226
. collect ( )
165
227
} else {
@@ -255,6 +317,7 @@ fn process(args: Args) -> Result<()> {
255
317
all,
256
318
allow_prerelease,
257
319
dry_run,
320
+ to_lockfile,
258
321
..
259
322
} = args;
260
323
@@ -268,7 +331,7 @@ fn process(args: Args) -> Result<()> {
268
331
Manifests :: get_local_one ( & manifest_path)
269
332
} ?;
270
333
271
- let existing_dependencies = manifests. get_dependencies ( dependency) ?;
334
+ let existing_dependencies = manifests. get_dependencies ( dependency, to_lockfile ) ?;
272
335
273
336
let upgraded_dependencies =
274
337
existing_dependencies. get_upgraded ( allow_prerelease, & find ( & manifest_path) ?) ?;
0 commit comments