fn update_root_toml()

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(())
}