diff --git a/tools/publisher/src/cargo.rs b/tools/publisher/src/cargo.rs index 051fa526647d781134f23f7ae389ecb9fb442408..cdc37f5570fea07fedc76fd036c28509bec17770 100644 --- a/tools/publisher/src/cargo.rs +++ b/tools/publisher/src/cargo.rs @@ -8,11 +8,13 @@ mod add_owner; mod get_owners; mod publish; +mod remove_owner; mod yank; pub use add_owner::AddOwner; pub use get_owners::GetOwners; pub use publish::Publish; +pub use remove_owner::RemoveOwner; pub use yank::Yank; use anyhow::{Context, Result}; diff --git a/tools/publisher/src/cargo/remove_owner.rs b/tools/publisher/src/cargo/remove_owner.rs new file mode 100644 index 0000000000000000000000000000000000000000..416534023481eef51137c8170aaabe8bcb171198 --- /dev/null +++ b/tools/publisher/src/cargo/remove_owner.rs @@ -0,0 +1,78 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::Result; +use smithy_rs_tool_common::shell::{handle_failure, ShellOperation}; +use std::process::Command; + +pub struct RemoveOwner { + program: &'static str, + package_name: String, + owner: String, +} + +impl RemoveOwner { + pub fn new(package_name: impl Into, owner: impl Into) -> RemoveOwner { + RemoveOwner { + program: "cargo", + package_name: package_name.into(), + owner: owner.into(), + } + } +} + +impl ShellOperation for RemoveOwner { + type Output = (); + + fn run(&self) -> Result<()> { + let mut command = Command::new(self.program); + command + .arg("owner") + .arg("--remove") + .arg(&self.owner) + .arg(&self.package_name); + let output = command.output()?; + handle_failure("remove owner", &output)?; + Ok(()) + } +} + +#[cfg(all(test, not(target_os = "windows")))] +mod tests { + use super::*; + use smithy_rs_tool_common::shell::ShellOperation; + + #[tokio::test] + async fn remove_owner_success() { + RemoveOwner { + program: "./fake_cargo/cargo_success", + package_name: "aws-sdk-s3".into(), + owner: "incorrect_owner".into(), + } + .spawn() + .await + .unwrap(); + } + + #[tokio::test] + async fn remove_owner_failed() { + let result = RemoveOwner { + program: "./fake_cargo/cargo_fails", + package_name: "aws-sdk-s3".into(), + owner: "incorrect_owner".into(), + } + .spawn() + .await; + + assert!(result.is_err(), "expected error, got {:?}", result); + assert_eq!( + "Failed to remove owner:\n\ + Status: 1\n\ + Stdout: some stdout failure message\n\n\ + Stderr: some stderr failure message\n\n", + format!("{}", result.err().unwrap()) + ); + } +} diff --git a/tools/publisher/src/subcommand/publish.rs b/tools/publisher/src/subcommand/publish.rs index 5a7a18de5f9cc9fb740f45350f1cab2e578f6e7d..24de5274054ab7a80874c44f2995f6aa31c3b6d5 100644 --- a/tools/publisher/src/subcommand/publish.rs +++ b/tools/publisher/src/subcommand/publish.rs @@ -177,6 +177,17 @@ async fn correct_owner(package: &Package) -> Result<()> { Duration::from_secs(5), || async { let owners = cargo::GetOwners::new(&package.handle.name).spawn().await?; + let incorrect_owners = owners.iter().filter(|&owner| owner != CRATE_OWNER); + for incorrect_owner in incorrect_owners { + cargo::RemoveOwner::new(&package.handle.name, incorrect_owner) + .spawn() + .await + .context("remove incorrect owner")?; + info!( + "Removed incorrect owner `{}` from crate `{}`", + incorrect_owner, package.handle + ); + } if !owners.iter().any(|owner| owner == CRATE_OWNER) { cargo::AddOwner::new(&package.handle.name, CRATE_OWNER) .spawn()