#
cargo/ops/registry/
owner.rs

    1//! Interacts with the registry [owners API][1].
    2//!
    3//! [1]: https://doc.rust-lang.org/nightly/cargo/reference/registry-web-api.html#owners
    4
    5use anyhow::Context as _;
    6use cargo_credential::Operation;
    7use cargo_credential::Secret;
    8
    9use crate::core::Workspace;
    10use crate::drop_print;
    11use crate::drop_println;
    12use crate::util::important_paths::find_root_manifest_for_wd;
    13use crate::CargoResult;
    14use crate::GlobalContext;
    15
    16use super::RegistryOrIndex;
    17
    18pub struct OwnersOptions {
    19    pub krate: Option<String>,
    20    pub token: Option<Secret<String>>,
    21    pub reg_or_index: Option<RegistryOrIndex>,
    22    pub to_add: Option<Vec<String>>,
    23    pub to_remove: Option<Vec<String>>,
    24    pub list: bool,
    25}
    26
    27pub fn modify_owners(gctx: &GlobalContext, opts: &OwnersOptions) -> CargoResult<()> {
    28    let name = match opts.krate {
    29        Some(ref name) => name.clone(),
    30        None => {
    31            let manifest_path = find_root_manifest_for_wd(gctx.cwd())?;
    32            let ws = Workspace::new(&manifest_path, gctx)?;
    33            ws.current()?.package_id().name().to_string()
    34        }
    35    };
    36
    37    let operation = Operation::Owners { name: &name };
    38    let source_ids = super::get_source_id(gctx, opts.reg_or_index.as_ref())?;
    39    let (mut registry, _) = super::registry(
    40        gctx,
    41        &source_ids,
    42        opts.token.as_ref().map(Secret::as_deref),
    43        opts.reg_or_index.as_ref(),
    44        true,
    45        Some(operation),
    46    )?;
    47
    48    if let Some(ref v) = opts.to_add {
    49        let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
    50        let msg = registry.add_owners(&name, &v).with_context(|| {
    51            format!(
    52                "failed to invite owners to crate `{}` on registry at {}",
    53                name,
    54                registry.host()
    55            )
    56        })?;
    57
    58        gctx.shell().status("Owner", msg)?;
    59    }
    60
    61    if let Some(ref v) = opts.to_remove {
    62        let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
    63        gctx.shell()
    64            .status("Owner", format!("removing {:?} from crate {}", v, name))?;
    65        registry.remove_owners(&name, &v).with_context(|| {
    66            format!(
    67                "failed to remove owners from crate `{}` on registry at {}",
    68                name,
    69                registry.host()
    70            )
    71        })?;
    72    }
    73
    74    if opts.list {
    75        let owners = registry.list_owners(&name).with_context(|| {
    76            format!(
    77                "failed to list owners of crate `{}` on registry at {}",
    78                name,
    79                registry.host()
    80            )
    81        })?;
    82        for owner in owners.iter() {
    83            drop_print!(gctx, "{}", owner.login);
    84            match (owner.name.as_ref(), owner.email.as_ref()) {
    85                (Some(name), Some(email)) => drop_println!(gctx, " ({} <{}>)", name, email),
    86                (Some(s), None) | (None, Some(s)) => drop_println!(gctx, " ({})", s),
    87                (None, None) => drop_println!(gctx),
    88            }
    89        }
    90    }
    91
    92    Ok(())
    93}