    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75

    //! Interacts with the registry [yank] and [unyank] API.
    //!
    //! [yank]: https://doc.rust-lang.org/nightly/cargo/reference/registry-web-api.html#yank
    //! [unyank]: https://doc.rust-lang.org/nightly/cargo/reference/registry-web-api.html#unyank

    use anyhow::bail;
    use anyhow::Context as _;
    use cargo_credential::Operation;
    use cargo_credential::Secret;

    use crate::core::Workspace;
    use crate::util::config::Config;
    use crate::util::errors::CargoResult;
    use crate::util::important_paths::find_root_manifest_for_wd;

    use super::RegistryOrIndex;

    pub fn yank(
        config: &Config,
        krate: Option<String>,
        version: Option<String>,
        token: Option<Secret<String>>,
        reg_or_index: Option<RegistryOrIndex>,
        undo: bool,
    ) -> CargoResult<()> {
        let name = match krate {
            Some(name) => name,
            None => {
                let manifest_path = find_root_manifest_for_wd(config.cwd())?;
                let ws = Workspace::new(&manifest_path, config)?;
                ws.current()?.package_id().name().to_string()
            }
        };
        let Some(version) = version else {
            bail!("a version must be specified to yank")
        };

        let message = if undo {
            Operation::Unyank {
                name: &name,
                vers: &version,
            }
        } else {
            Operation::Yank {
                name: &name,
                vers: &version,
            }
        };

        let (mut registry, _) = super::registry(
            config,
            token.as_ref().map(Secret::as_deref),
            reg_or_index.as_ref(),
            true,
            Some(message),
        )?;

        let package_spec = format!("{}@{}", name, version);
        if undo {
            config.shell().status("Unyank", package_spec)?;
            registry.unyank(&name, &version).with_context(|| {
                format!(
                    "failed to undo a yank from the registry at {}",
                    registry.host()
                )
            })?;
        } else {
            config.shell().status("Yank", package_spec)?;
            registry
                .yank(&name, &version)
                .with_context(|| format!("failed to yank from the registry at {}", registry.host()))?;
        }

        Ok(())
    }