1
- use crate :: util:: { get_crates, Crate } ;
2
- use anyhow:: { bail , Context , Result } ;
1
+ use crate :: util:: { get_crates, get_top_level_cargo_toml , get_top_level_version , Crate } ;
2
+ use anyhow:: { Context , Result } ;
3
3
use clap:: Args ;
4
4
use semver:: { BuildMetadata , Prerelease } ;
5
5
use std:: fs;
@@ -26,17 +26,10 @@ impl BumpCommand {
26
26
let publishable_crates: Vec < Crate > =
27
27
get_crates ( ) ?. into_iter ( ) . filter ( |c| c. publish ) . collect ( ) ;
28
28
29
- // Check that all of the versions are the same.
30
- if !publishable_crates
31
- . windows ( 2 )
32
- . all ( |w| w[ 0 ] . version == w[ 1 ] . version )
33
- {
34
- bail ! ( "Not all crate versions are the same: {publishable_crates:?}" ) ;
35
- }
36
-
37
29
// Change the version. Unless specified with a custom version, the `pre` and `build`
38
30
// metadata are cleared.
39
- let mut next_version = semver:: Version :: parse ( & publishable_crates[ 0 ] . version ) ?;
31
+ let current_version = get_top_level_version ( ) ?;
32
+ let mut next_version = current_version. clone ( ) ;
40
33
next_version. pre = Prerelease :: EMPTY ;
41
34
next_version. build = BuildMetadata :: EMPTY ;
42
35
match & self . bump {
@@ -55,11 +48,17 @@ impl BumpCommand {
55
48
Bump :: Custom ( v) => next_version = semver:: Version :: parse ( v) ?,
56
49
}
57
50
58
- // Update the Cargo.toml files.
59
- let next_version_str = & next_version. to_string ( ) ;
60
- for c in & publishable_crates {
61
- update_version ( c, & publishable_crates, next_version_str, self . dry_run ) ?;
62
- }
51
+ // Update the top-level Cargo.toml version. We expect all the crates use the top-level
52
+ // workspace version.
53
+ assert ! ( publishable_crates. iter( ) . all( uses_workspace_version) ) ;
54
+ let current_version_str = current_version. to_string ( ) ;
55
+ let next_version_str = next_version. to_string ( ) ;
56
+ update_version (
57
+ & publishable_crates,
58
+ & current_version_str,
59
+ & next_version_str,
60
+ self . dry_run ,
61
+ ) ?;
63
62
64
63
// Update the Cargo.lock file.
65
64
if !self . dry_run {
@@ -107,29 +106,41 @@ impl std::str::FromStr for Bump {
107
106
}
108
107
}
109
108
110
- /// Update the version of `krate` and any dependencies in `crates` to match the version passed in
111
- /// `next_version`. Adapted from Wasmtime's [publish.rs] script.
109
+ /// Check that a publishable crate pulls its version from the workspace version.
110
+ fn uses_workspace_version ( krate : & Crate ) -> bool {
111
+ let contents = fs:: read_to_string ( & krate. path ) . unwrap ( ) ;
112
+ let toml: toml:: Value = contents. parse ( ) . unwrap ( ) ;
113
+ let version_workspace = & toml[ "package" ] [ "version" ] [ "workspace" ] ;
114
+ * version_workspace == toml:: Value :: Boolean ( true )
115
+ }
116
+
117
+ /// Update the version in the top-level Cargo.toml and any dependencies in its
118
+ /// `[workspace.dependencies]` to match the version passed in `next_version`. Adapted from
119
+ /// Wasmtime's [publish.rs] script.
112
120
///
113
121
/// [publish.rs]: https://github.com/bytecodealliance/wasmtime/blob/main/scripts/publish.rs
114
122
fn update_version (
115
- krate : & Crate ,
116
123
crates : & [ Crate ] ,
124
+ current_version : & str ,
117
125
next_version : & str ,
118
126
dry_run : bool ,
119
127
) -> Result < ( ) > {
120
- let contents = fs:: read_to_string ( & krate. path ) ?;
128
+ let top_level_cargo_toml_path = get_top_level_cargo_toml ( ) ?;
129
+ let contents = fs:: read_to_string ( & top_level_cargo_toml_path) ?;
121
130
let mut new_contents = String :: new ( ) ;
122
131
let mut reading_dependencies = false ;
123
132
for line in contents. lines ( ) {
124
133
let mut rewritten = false ;
125
134
126
135
// Update top-level `version = "..."` line.
127
136
if !reading_dependencies && line. starts_with ( "version =" ) {
137
+ let modified_line = line. replace ( current_version, next_version) ;
128
138
println ! (
129
- "> bump `{}` {} => {}" ,
130
- krate. name, krate. version, next_version
139
+ "> bump: {} => {}" ,
140
+ line. trim_start_matches( "version =" ) . trim( ) ,
141
+ modified_line. trim_start_matches( "version =" ) . trim( )
131
142
) ;
132
- new_contents. push_str ( & line . replace ( & krate . version . to_string ( ) , next_version ) ) ;
143
+ new_contents. push_str ( & modified_line ) ;
133
144
rewritten = true ;
134
145
}
135
146
@@ -145,21 +156,21 @@ fn update_version(
145
156
if !reading_dependencies || !line. starts_with ( & format ! ( "{} " , other. name) ) {
146
157
continue ;
147
158
}
148
- if !line. contains ( & other . version . to_string ( ) ) {
159
+ if !line. contains ( current_version ) {
149
160
if !line. contains ( "version =" ) {
150
161
continue ;
151
162
}
152
163
panic ! (
153
- "{:?} has a dependency on {} but doesn't list version {}" ,
154
- krate . path , other. name, other . version
164
+ "workspace dependency {} doesn't list version {}" ,
165
+ other. name, current_version
155
166
) ;
156
167
}
157
168
println ! (
158
169
"> bump dependency `{}` {} => {}" ,
159
- other. name, other . version , next_version
170
+ other. name, current_version , next_version
160
171
) ;
161
172
rewritten = true ;
162
- new_contents. push_str ( & line. replace ( & other . version , next_version) ) ;
173
+ new_contents. push_str ( & line. replace ( current_version , next_version) ) ;
163
174
break ;
164
175
}
165
176
@@ -172,7 +183,7 @@ fn update_version(
172
183
}
173
184
174
185
if !dry_run {
175
- fs:: write ( & krate . path , new_contents) ?;
186
+ fs:: write ( top_level_cargo_toml_path , new_contents) ?;
176
187
}
177
188
178
189
Ok ( ( ) )
0 commit comments