Skip to content

Commit 31579f0

Browse files
authored
Fix bump_crate_versions to update [workspace.dependencies] (#2708)
1 parent 0a64630 commit 31579f0

1 file changed

Lines changed: 50 additions & 8 deletions

File tree

  • source/tools/bump_crate_versions/src

source/tools/bump_crate_versions/src/main.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ use toml_edit::DocumentMut;
1515

1616
const LINE_COUNT_DIR: &str = "source/tools/line_count";
1717

18+
// Manifest of the `source` workspace, which centralizes the versions of our internal
19+
// crates in its [workspace.dependencies] table
20+
const WORKSPACE_MANIFEST: &str = "source/Cargo.toml";
21+
1822
/// This tool scans for modified crates in the Verus repository and updates the version numbers
1923
/// in their respective Cargo.toml files. In cases where one crate depends on another, we also
2024
/// update the version of the dependency in the dependent crate's Cargo.toml. Finally, when vstd
@@ -203,6 +207,13 @@ fn update_toml_version(dir: &Path) {
203207
fs::write(&cargo_toml_path, content).expect("Failed to write Cargo.toml");
204208
}
205209

210+
// Reports whether a dependency entry is of the form `{ workspace = true }`, meaning it
211+
// inherits its version from the workspace's [workspace.dependencies] table. Cargo ignores
212+
// a `version` key on such an entry, so we must update the workspace table instead.
213+
fn inherits_from_workspace(entry: &toml_edit::Item) -> bool {
214+
entry.get("workspace").and_then(|w| w.as_bool()).unwrap_or(false)
215+
}
216+
206217
fn update_toml_dependencies(dir: &Path, dependencies: &Vec<&Crate>) {
207218
let cargo_toml_path = dir.join("Cargo.toml");
208219

@@ -211,23 +222,51 @@ fn update_toml_dependencies(dir: &Path, dependencies: &Vec<&Crate>) {
211222
.unwrap_or_else(|e| panic!("Failed to read {}: {e:?}", cargo_toml_path.display()));
212223
let mut doc = content.parse::<DocumentMut>().expect("Failed to parse Cargo.toml");
213224

214-
// Update dependencies with the new version
225+
// Update dependencies with the new version, skipping any whose version the workspace dictates
215226
for krate in dependencies {
216-
if doc.contains_key("dependencies") && doc["dependencies"].get(&krate.name).is_some() {
217-
doc["dependencies"][&krate.name]["version"] =
218-
toml_edit::value(format!("={}", *NEW_VERSION));
227+
for table in ["dependencies", "dev-dependencies"] {
228+
if doc
229+
.get(table)
230+
.and_then(|t| t.get(&krate.name))
231+
.is_some_and(|entry| !inherits_from_workspace(entry))
232+
{
233+
doc[table][&krate.name]["version"] = toml_edit::value(format!("={}", *NEW_VERSION));
234+
}
219235
}
220-
if doc.contains_key("dev-dependencies")
221-
&& doc["dev-dependencies"].get(&krate.name).is_some()
236+
}
237+
238+
// Write the updated content back to Cargo.toml
239+
let content = doc.to_string();
240+
fs::write(&cargo_toml_path, content).expect("Failed to write Cargo.toml");
241+
}
242+
243+
// Update the versions recorded in a workspace's [workspace.dependencies] table. Members that
244+
// declare a dependency as `{ workspace = true }` inherit their version from this table, so it
245+
// is the only place those versions can be updated. Note that this does not affect the crates
246+
// under dependencies/, since they are not members of this workspace and hence pin their
247+
// versions directly.
248+
fn update_workspace_dependencies(manifest: &Path, dependencies: &Vec<&Crate>) {
249+
// Read the Cargo.toml file
250+
let content = fs::read_to_string(manifest)
251+
.unwrap_or_else(|e| panic!("Failed to read {}: {e:?}", manifest.display()));
252+
let mut doc = content.parse::<DocumentMut>().expect("Failed to parse Cargo.toml");
253+
254+
for krate in dependencies {
255+
if doc
256+
.get("workspace")
257+
.and_then(|w| w.get("dependencies"))
258+
.and_then(|d| d.get(&krate.name))
259+
.is_some()
222260
{
223-
doc["dev-dependencies"][&krate.name]["version"] =
261+
doc["workspace"]["dependencies"][&krate.name]["version"] =
224262
toml_edit::value(format!("={}", *NEW_VERSION));
225263
}
226264
}
227265

228266
// Write the updated content back to Cargo.toml
229267
let content = doc.to_string();
230-
fs::write(&cargo_toml_path, content).expect("Failed to write Cargo.toml");
268+
fs::write(manifest, content)
269+
.unwrap_or_else(|e| panic!("Failed to write {}: {e:?}", manifest.display()));
231270
}
232271

233272
fn publish(dir: &Path, dry_run: bool) {
@@ -339,6 +378,9 @@ fn update_crates(crates: Vec<Crate>) {
339378
}
340379
}
341380

381+
// Update the versions that the workspace's members inherit
382+
update_workspace_dependencies(Path::new(WORKSPACE_MANIFEST), &modified_crates);
383+
342384
// Finally, update the line count tool's dependencies if needed
343385
update_toml_dependencies(Path::new(LINE_COUNT_DIR), &modified_crates);
344386
}

0 commit comments

Comments
 (0)