@@ -95,6 +95,33 @@ struct Args {
95
95
/// A collection of manifests.
96
96
struct Manifests ( Vec < ( LocalManifest , cargo_metadata:: Package ) > ) ;
97
97
98
+ /// Helper function to check whether a `cargo_metadata::Dependency` is a version dependency.
99
+ fn is_version_dep ( dependency : & cargo_metadata:: Dependency ) -> bool {
100
+ match dependency. source {
101
+ // This is the criterion cargo uses (in `SourceId::from_url`) to decide whether a
102
+ // dependency has the 'registry' kind.
103
+ Some ( ref s) => s. splitn ( 2 , '+' ) . next ( ) == Some ( "registry" ) ,
104
+ _ => false ,
105
+ }
106
+ }
107
+
108
+ fn dry_run_message ( ) -> Result < ( ) > {
109
+ let bufwtr = BufferWriter :: stdout ( ColorChoice :: Always ) ;
110
+ let mut buffer = bufwtr. buffer ( ) ;
111
+ buffer
112
+ . set_color ( ColorSpec :: new ( ) . set_fg ( Some ( Color :: Cyan ) ) . set_bold ( true ) )
113
+ . chain_err ( || "Failed to set output colour" ) ?;
114
+ write ! ( & mut buffer, "Starting dry run. " ) . chain_err ( || "Failed to write dry run message" ) ?;
115
+ buffer
116
+ . set_color ( & ColorSpec :: new ( ) )
117
+ . chain_err ( || "Failed to clear output colour" ) ?;
118
+ writeln ! ( & mut buffer, "Changes will not be saved." )
119
+ . chain_err ( || "Failed to write dry run message" ) ?;
120
+ bufwtr
121
+ . print ( & buffer)
122
+ . chain_err ( || "Failed to print dry run message" )
123
+ }
124
+
98
125
impl Manifests {
99
126
/// Get all manifests in the workspace.
100
127
fn get_all ( manifest_path : & Option < PathBuf > ) -> Result < Self > {
@@ -148,80 +175,16 @@ impl Manifests {
148
175
Ok ( Manifests ( vec ! [ ( manifest, package. to_owned( ) ) ] ) )
149
176
}
150
177
151
- fn get_all_requested_dependencies ( & self ) -> Vec < cargo_metadata:: Dependency > {
152
- /// Helper function to check whether a `cargo_metadata::Dependency` is a version dependency.
153
- fn is_version_dep ( dependency : & cargo_metadata:: Dependency ) -> bool {
154
- match dependency. source {
155
- // This is the criterion cargo uses (in `SourceId::from_url`) to decide whether a
156
- // dependency has the 'registry' kind.
157
- Some ( ref s) => s. splitn ( 2 , '+' ) . next ( ) == Some ( "registry" ) ,
158
- _ => false ,
159
- }
160
- }
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
178
/// Get the the combined set of dependencies to upgrade. If the user has specified
195
179
/// 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
-
180
+ fn get_dependencies ( & self , only_update : Vec < String > ) -> Result < DesiredUpgrades > {
220
181
Ok ( DesiredUpgrades ( if only_update. is_empty ( ) {
221
182
// User hasn't asked for any specific dependencies to be upgraded, so upgrade all the
222
183
// dependencies.
223
- self . get_all_requested_dependencies ( )
224
- . into_iter ( )
184
+ self . 0
185
+ . iter ( )
186
+ . flat_map ( |& ( _, ref package) | package. dependencies . clone ( ) )
187
+ . filter ( is_version_dep)
225
188
. map ( |dependency| ( dependency. name , None ) )
226
189
. collect ( )
227
190
} else {
@@ -244,21 +207,7 @@ impl Manifests {
244
207
/// Upgrade the manifests on disk following the previously-determined upgrade schema.
245
208
fn upgrade ( self , upgraded_deps : & ActualUpgrades , dry_run : bool ) -> Result < ( ) > {
246
209
if dry_run {
247
- let bufwtr = BufferWriter :: stdout ( ColorChoice :: Always ) ;
248
- let mut buffer = bufwtr. buffer ( ) ;
249
- buffer
250
- . set_color ( ColorSpec :: new ( ) . set_fg ( Some ( Color :: Cyan ) ) . set_bold ( true ) )
251
- . chain_err ( || "Failed to set output colour" ) ?;
252
- write ! ( & mut buffer, "Starting dry run. " )
253
- . chain_err ( || "Failed to write dry run message" ) ?;
254
- buffer
255
- . set_color ( & ColorSpec :: new ( ) )
256
- . chain_err ( || "Failed to clear output colour" ) ?;
257
- writeln ! ( & mut buffer, "Changes will not be saved." )
258
- . chain_err ( || "Failed to write dry run message" ) ?;
259
- bufwtr
260
- . print ( & buffer)
261
- . chain_err ( || "Failed to print dry run message" ) ?;
210
+ dry_run_message ( ) ?;
262
211
}
263
212
264
213
for ( mut manifest, package) in self . 0 {
@@ -271,6 +220,58 @@ impl Manifests {
271
220
272
221
Ok ( ( ) )
273
222
}
223
+
224
+ /// Update dependencies in Cargo.toml file(s) to match the corresponding
225
+ /// version in Cargo.lock.
226
+ fn sync_to_lockfile ( self , dry_run : bool ) -> Result < ( ) > {
227
+ // Get locked dependencies. If there may be multiple Cargo.toml
228
+ // files in the workspace, then they all share the same lockfile,
229
+ // so it suffices to get the query metadata for any one of them.
230
+ let ( manifest, _package) = self . 0 . iter ( ) . next ( ) . expect ( "should have one" ) ;
231
+ let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
232
+ cmd. manifest_path ( manifest. path . clone ( ) ) ;
233
+ cmd. other_options ( vec ! [ "--locked" . to_string( ) ] ) ;
234
+
235
+ let result = cmd
236
+ . exec ( )
237
+ . map_err ( |e| Error :: from ( e. compat ( ) ) . chain_err ( || "Invalid manifest" ) ) ?;
238
+
239
+ let locked = result
240
+ . packages
241
+ . into_iter ( )
242
+ . filter ( |p| p. source . is_some ( ) ) // Source is none for local packages
243
+ . collect :: < Vec < _ > > ( ) ;
244
+
245
+ if dry_run {
246
+ dry_run_message ( ) ?;
247
+ }
248
+
249
+ for ( mut manifest, package) in self . 0 {
250
+ println ! ( "{}:" , package. name) ;
251
+
252
+ // Upgrade the manifests one at a time, as multiple manifests may
253
+ // request the same dependency at differing versions.
254
+ for ( name, version) in package
255
+ . dependencies
256
+ . clone ( )
257
+ . into_iter ( )
258
+ . filter ( is_version_dep)
259
+ . filter_map ( |d| {
260
+ for p in & locked {
261
+ // The requested depenency may be present in the lock file with different versions,
262
+ // but only one will be semver-compatible with requested version.
263
+ if d. name == p. name && d. req . matches ( & p. version ) {
264
+ return Some ( ( d. name , p. version . to_string ( ) ) ) ;
265
+ }
266
+ }
267
+ return None ;
268
+ } )
269
+ {
270
+ manifest. upgrade ( & Dependency :: new ( & name) . set_version ( & version) , dry_run) ?;
271
+ }
272
+ }
273
+ Ok ( ( ) )
274
+ }
274
275
}
275
276
276
277
/// The set of dependencies to be upgraded, alongside desired versions, if specified by the user.
@@ -331,12 +332,16 @@ fn process(args: Args) -> Result<()> {
331
332
Manifests :: get_local_one ( & manifest_path)
332
333
} ?;
333
334
334
- let existing_dependencies = manifests. get_dependencies ( dependency, to_lockfile) ?;
335
+ if to_lockfile {
336
+ manifests. sync_to_lockfile ( dry_run)
337
+ } else {
338
+ let existing_dependencies = manifests. get_dependencies ( dependency) ?;
335
339
336
- let upgraded_dependencies =
337
- existing_dependencies. get_upgraded ( allow_prerelease, & find ( & manifest_path) ?) ?;
340
+ let upgraded_dependencies =
341
+ existing_dependencies. get_upgraded ( allow_prerelease, & find ( & manifest_path) ?) ?;
338
342
339
- manifests. upgrade ( & upgraded_dependencies, dry_run)
343
+ manifests. upgrade ( & upgraded_dependencies, dry_run)
344
+ }
340
345
}
341
346
342
347
fn main ( ) {
0 commit comments