in cargo-guppy/src/mv.rs [451:513]
fn update_root_toml(
workspace_root: &Utf8Path,
src_moves: &BTreeMap<&Utf8Path, PackageMove<'_>>,
) -> Result<()> {
let root_manifest_path = workspace_root.join("Cargo.toml");
let mut document = read_toml(&root_manifest_path)?;
// Fix up paths in workspace.members or workspace.default-members.
let workspace_table = match document.as_table_mut().get_mut("workspace") {
Some(item) => item
.as_table_mut()
.ok_or_else(|| eyre!("[workspace] is not a table"))?,
None => {
// No [workspace] section -- possibly a single-crate manifest?
return Ok(());
}
};
static TO_UPDATE: &[&str] = &["members", "default-members"];
for to_update in TO_UPDATE {
let members = match workspace_table.get_mut(to_update) {
Some(item) => item
.as_array_mut()
.ok_or_else(|| eyre!("in [workspace], {} is not an array", to_update))?,
None => {
// default-members may not always exist.
continue;
}
};
for idx in 0..members.len() {
let member = members.get(idx).expect("valid idx");
match member.as_str() {
Some(path) => {
let abs_member_dir = workspace_root.join(path);
// The workspace path saved in the TOML may not be in canonical form.
let abs_member_dir = abs_member_dir.canonicalize().wrap_err_with(|| {
eyre!(
"in [workspace] {}, error while canonicalizing path {}",
to_update,
path
)
})?;
// member dir is the canonical dir relative to the root.
let member_dir = rel_path(&abs_member_dir, workspace_root)?;
if let Some(package_move) = src_moves.get(member_dir) {
// This path was moved.
members.replace(idx, package_move.new_path.as_str());
}
}
None => bail!("in [workspace], {} contains non-strings", to_update),
}
}
}
let mut out = fs::File::create(&root_manifest_path)
.wrap_err_with(|| eyre!("Error while opening {}", root_manifest_path))?;
write!(out, "{}", document)?;
Ok(())
}