Unverified Commit 69efe3a7 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Don't generate a SDK for runtime-versioner patching (#3540)

This PR removes the requirement of generating a SDK in order to patch
smithy-rs runtime crates into an already released SDK version for
testing. This is possible now that all the runtime crates are
independently versioned. The tool also takes multiple paths as input for
the runtime crate locations. This makes it possible to pass in the
`rust-runtime` and `aws/rust-runtime` directories from smithy-rs (done
by default by one of the subcommands).

Some of the publisher tool's package resolution code is moved into
smithy-rs-tool-common so it can be better shared across the tools, and
as part of this, the version in the package handle was made optional.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 7db0f736
Loading
Loading
Loading
Loading
+146 −3
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
 "hermit-abi",
 "hermit-abi 0.1.19",
 "libc",
 "winapi",
]
@@ -105,6 +105,16 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"

[[package]]
name = "cargo_toml"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be"
dependencies = [
 "serde",
 "toml 0.8.12",
]

[[package]]
name = "cc"
version = "1.0.83"
@@ -134,7 +144,7 @@ dependencies = [
 "smithy-rs-tool-common",
 "tempfile",
 "time",
 "toml",
 "toml 0.5.11",
]

[[package]]
@@ -192,6 +202,26 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"

[[package]]
name = "crates-index"
version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d9efa03a974d583ad530bbfe00e3d0021de7f26217120437b128dc4c331aa4f"
dependencies = [
 "hex",
 "home",
 "http",
 "memchr",
 "rustc-hash",
 "semver",
 "serde",
 "serde_derive",
 "serde_json",
 "smol_str",
 "thiserror",
 "toml 0.8.12",
]

[[package]]
name = "deranged"
version = "0.3.10"
@@ -283,6 +313,12 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"

[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"

[[package]]
name = "futures-sink"
version = "0.3.29"
@@ -302,9 +338,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
dependencies = [
 "futures-core",
 "futures-io",
 "futures-task",
 "memchr",
 "pin-project-lite",
 "pin-utils",
 "slab",
]

[[package]]
@@ -359,6 +398,30 @@ dependencies = [
 "libc",
]

[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"

[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
dependencies = [
 "serde",
]

[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
 "windows-sys 0.52.0",
]

[[package]]
name = "http"
version = "0.2.11"
@@ -574,6 +637,16 @@ dependencies = [
 "autocfg",
]

[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
 "hermit-abi 0.3.9",
 "libc",
]

[[package]]
name = "num_threads"
version = "0.1.6"
@@ -821,6 +894,12 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"

[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"

[[package]]
name = "rustix"
version = "0.38.26"
@@ -909,6 +988,15 @@ dependencies = [
 "serde",
]

[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
 "serde",
]

[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -936,6 +1024,8 @@ version = "0.1.0"
dependencies = [
 "anyhow",
 "async-trait",
 "cargo_toml",
 "crates-index",
 "lazy_static",
 "regex",
 "reqwest",
@@ -943,10 +1033,19 @@ dependencies = [
 "serde",
 "serde_json",
 "thiserror",
 "toml",
 "toml 0.5.11",
 "tracing",
]

[[package]]
name = "smol_str"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49"
dependencies = [
 "serde",
]

[[package]]
name = "socket2"
version = "0.4.10"
@@ -1109,6 +1208,7 @@ dependencies = [
 "bytes",
 "libc",
 "mio",
 "num_cpus",
 "pin-project-lite",
 "socket2 0.5.5",
 "windows-sys 0.48.0",
@@ -1148,6 +1248,40 @@ dependencies = [
 "serde",
]

[[package]]
name = "toml"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
dependencies = [
 "serde",
 "serde_spanned",
 "toml_datetime",
 "toml_edit",
]

[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
 "serde",
]

[[package]]
name = "toml_edit"
version = "0.22.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
dependencies = [
 "indexmap 2.1.0",
 "serde",
 "serde_spanned",
 "toml_datetime",
 "winnow",
]

[[package]]
name = "tower-service"
version = "0.3.2"
@@ -1489,6 +1623,15 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"

[[package]]
name = "winnow"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
dependencies = [
 "memchr",
]

[[package]]
name = "winreg"
version = "0.50.0"
+12 −1
Original line number Diff line number Diff line
@@ -135,6 +135,16 @@ dependencies = [
 "toml 0.8.12",
]

[[package]]
name = "cargo_toml"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be"
dependencies = [
 "serde",
 "toml 0.8.12",
]

[[package]]
name = "cc"
version = "1.0.90"
@@ -956,7 +966,7 @@ dependencies = [
 "anyhow",
 "async-recursion",
 "async-trait",
 "cargo_toml",
 "cargo_toml 0.16.3",
 "clap",
 "dialoguer",
 "fs-err",
@@ -1278,6 +1288,7 @@ version = "0.1.0"
dependencies = [
 "anyhow",
 "async-trait",
 "cargo_toml 0.19.2",
 "crates-index",
 "lazy_static",
 "regex",
+14 −11
Original line number Diff line number Diff line
@@ -3,9 +3,11 @@
 * SPDX-License-Identifier: Apache-2.0
 */

use crate::package::PackageHandle;
use anyhow::Result;
use smithy_rs_tool_common::shell::{capture_error, output_text, ShellOperation};
use smithy_rs_tool_common::{
    package::PackageHandle,
    shell::{capture_error, output_text, ShellOperation},
};
use std::path::PathBuf;
use std::process::Command;
use tracing::info;
@@ -18,6 +20,10 @@ pub struct Publish {

impl Publish {
    pub fn new(package_handle: PackageHandle, package_path: impl Into<PathBuf>) -> Publish {
        assert!(
            package_handle.version.is_some(),
            "crate version number required; given {package_handle}"
        );
        Publish {
            program: "cargo",
            package_handle,
@@ -42,12 +48,12 @@ impl ShellOperation for Publish {
            let (stdout, stderr) = output_text(&output);
            let already_uploaded_msg = format!(
                "error: crate version `{}` is already uploaded",
                self.package_handle.version
                self.package_handle.expect_version()
            );
            if stdout.contains(&already_uploaded_msg) || stderr.contains(&already_uploaded_msg) {
                info!(
                    "{}-{} has already been published to crates.io.",
                    self.package_handle.name, self.package_handle.version
                    "{} has already been published to crates.io.",
                    self.package_handle
                );
            } else {
                return Err(capture_error("cargo publish", &output));
@@ -69,7 +75,7 @@ mod tests {
            program: "./fake_cargo/cargo_success",
            package_handle: PackageHandle::new(
                "aws-sdk-dynamodb",
                Version::parse("0.0.22-alpha").unwrap(),
                Version::parse("0.0.22-alpha").ok(),
            ),
            package_path: env::current_dir().unwrap(),
        }
@@ -82,10 +88,7 @@ mod tests {
    async fn publish_fails() {
        let result = Publish {
            program: "./fake_cargo/cargo_fails",
            package_handle: PackageHandle::new(
                "something",
                Version::parse("0.0.22-alpha").unwrap(),
            ),
            package_handle: PackageHandle::new("something", Version::parse("0.0.22-alpha").ok()),
            package_path: env::current_dir().unwrap(),
        }
        .spawn()
@@ -106,7 +109,7 @@ mod tests {
            program: "./fake_cargo/cargo_publish_already_published",
            package_handle: PackageHandle::new(
                "aws-sdk-dynamodb",
                Version::parse("0.0.22-alpha").unwrap(),
                Version::parse("0.0.22-alpha").ok(),
            ),
            package_path: env::current_dir().unwrap(),
        }
+20 −239
Original line number Diff line number Diff line
@@ -7,101 +7,15 @@

use crate::fs::Fs;
use crate::sort::dependency_order;
use crate::RUST_SDK_CI_OWNER;
use anyhow::{Context, Result};
use cargo_toml::{Dependency, DepsSet, Manifest};
use anyhow::Result;
use semver::Version;
use smithy_rs_tool_common::package::PackageCategory;
use std::collections::{BTreeMap, BTreeSet, HashSet};
use smithy_rs_tool_common::package::{Package, PackageCategory, PackageHandle, Publish};
use std::error::Error as StdError;
use std::fmt;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::{collections::BTreeMap, path::Path};
use tokio::fs;
use tracing::warn;

/// Information required to identify a package (crate).
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct PackageHandle {
    pub name: String,
    pub version: Version,
}

impl PackageHandle {
    pub fn new(name: impl Into<String>, version: Version) -> Self {
        Self {
            name: name.into(),
            version,
        }
    }
}

impl fmt::Display for PackageHandle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}-{}", self.name, self.version)
    }
}

#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum Publish {
    Allowed,
    NotAllowed,
}

/// Represents a crate (called Package since crate is a reserved word).
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Package {
    /// Package name and version information
    pub handle: PackageHandle,
    /// Package category (Generated, SmithyRuntime, AwsRuntime, etc.)
    pub category: PackageCategory,
    /// Location to the crate on the current file system
    pub crate_path: PathBuf,
    /// Location to the crate manifest on the current file system
    pub manifest_path: PathBuf,
    /// Dependencies used by this package
    pub local_dependencies: BTreeSet<PackageHandle>,
    /// Whether or not the package should be published
    pub publish: Publish,
}

impl Package {
    pub fn new(
        handle: PackageHandle,
        manifest_path: impl Into<PathBuf>,
        local_dependencies: BTreeSet<PackageHandle>,
        publish: Publish,
    ) -> Self {
        let manifest_path = manifest_path.into();
        let category = PackageCategory::from_package_name(&handle.name);
        Self {
            handle,
            category,
            crate_path: manifest_path.parent().unwrap().into(),
            manifest_path,
            local_dependencies,
            publish,
        }
    }

    /// Returns `true` if this package depends on `other`
    pub fn locally_depends_on(&self, other: &PackageHandle) -> bool {
        self.local_dependencies.contains(other)
    }

    /// Returns the expected owners of the crate.
    pub fn expected_owners(&self) -> HashSet<String> {
        expected_package_owners(&self.category, &self.handle.name)
    }
}

/// Returns the expected owners of the crate.
pub fn expected_package_owners(
    _category: &PackageCategory,
    _package_name: &str,
) -> HashSet<String> {
    [RUST_SDK_CI_OWNER.to_string()].into_iter().collect()
}

/// Batch of packages.
pub type PackageBatch = Vec<Package>;

@@ -145,7 +59,7 @@ pub async fn discover_and_validate_package_batches(
    fs: Fs,
    path: impl AsRef<Path>,
) -> Result<(Vec<PackageBatch>, PackageStats)> {
    let packages = discover_packages(fs, path.as_ref().into())
    let packages = discover_packages(fs, path.as_ref())
        .await?
        .into_iter()
        .filter(|package| package.publish == Publish::Allowed)
@@ -175,9 +89,9 @@ pub enum Error {

/// Discovers all Cargo.toml files under the given path recursively
#[async_recursion::async_recursion]
pub async fn discover_manifests(path: PathBuf) -> Result<Vec<PathBuf>> {
pub async fn discover_manifests(path: &Path) -> Result<Vec<PathBuf>> {
    let mut manifests = Vec::new();
    let mut read_dir = fs::read_dir(&path).await?;
    let mut read_dir = fs::read_dir(path).await?;
    while let Some(entry) = read_dir.next_entry().await? {
        let package_path = entry.path();
        if package_path.is_dir() {
@@ -185,91 +99,35 @@ pub async fn discover_manifests(path: PathBuf) -> Result<Vec<PathBuf>> {
            if manifest_path.exists() {
                manifests.push(manifest_path);
            }
            manifests.extend(discover_manifests(package_path).await?.into_iter());
            manifests.extend(discover_manifests(&package_path).await?.into_iter());
        }
    }
    Ok(manifests)
}

/// Discovers and parses all Cargo.toml files that are packages (as opposed to being exclusively workspaces)
pub async fn discover_packages(fs: Fs, path: PathBuf) -> Result<Vec<Package>> {
pub async fn discover_packages(fs: Fs, path: &Path) -> Result<Vec<Package>> {
    let manifest_paths = discover_manifests(path).await?;
    read_packages(fs, manifest_paths).await
}

/// Parses a semver version number and adds additional error context when parsing fails.
pub fn parse_version(manifest_path: &Path, version: &str) -> Result<Version, Error> {
    Version::parse(version)
        .map_err(|err| Error::InvalidCrateVersion(manifest_path.into(), version.into(), err.into()))
}

fn read_dependencies(path: &Path, dependencies: &DepsSet) -> Result<Vec<PackageHandle>> {
    let mut result = Vec::new();
    for (name, metadata) in dependencies {
        match metadata {
            Dependency::Simple(_) => {}
            Dependency::Detailed(detailed) => {
                if detailed.path.is_some() {
                    let version = detailed
                        .version
                        .as_ref()
                        .map(|version| parse_version(path, version))
                        .ok_or_else(|| Error::MissingVersion(path.into(), name.into()))??;
                    result.push(PackageHandle::new(name, version));
                }
            }
            Dependency::Inherited(_) => panic!("workspace deps are unsupported"),
        }
    }
    Ok(result)
}

/// Returns `Ok(None)` when the Cargo.toml is a workspace rather than a package
fn read_package(path: &Path, manifest_bytes: &[u8]) -> Result<Option<Package>> {
    let mut manifest = Manifest::from_slice(manifest_bytes)
        .with_context(|| format!("failed to load package manifest for {:?}", path))?;
    manifest.complete_from_path(path)?;
    if let Some(package) = manifest.package {
        let name = package.name;
        let version = parse_version(path, &package.version.unwrap())?;
        let handle = PackageHandle { name, version };
        let publish = match package.publish.unwrap() {
            cargo_toml::Publish::Flag(true) => Publish::Allowed,
            _ => Publish::NotAllowed,
        };

        let mut local_dependencies = BTreeSet::new();
        local_dependencies.extend(read_dependencies(path, &manifest.dependencies)?);
        local_dependencies.extend(read_dependencies(path, &manifest.dev_dependencies)?);
        local_dependencies.extend(read_dependencies(path, &manifest.build_dependencies)?);
        Ok(Some(Package::new(
            handle,
            path,
            local_dependencies,
            publish,
        )))
    } else {
        Ok(None)
    }
}

/// Validates that all of the publishable crates use consistent version numbers
/// across all of their local dependencies.
fn validate_packages(packages: &[Package]) -> Result<()> {
    let mut versions: BTreeMap<String, Version> = BTreeMap::new();
    let track_version = &mut |handle: &PackageHandle| -> Result<(), Error> {
        if let Some(version) = versions.get(&handle.name) {
            if *version != handle.version {
            if version != handle.expect_version() {
                Err(Error::MultipleVersions(
                    (&handle.name).into(),
                    versions[&handle.name].clone(),
                    handle.version.clone(),
                    handle.expect_version().clone(),
                ))
            } else {
                Ok(())
            }
        } else {
            versions.insert(handle.name.clone(), handle.version.clone());
            versions.insert(handle.name.clone(), handle.expect_version().clone());
            Ok(())
        }
    };
@@ -287,7 +145,7 @@ pub async fn read_packages(fs: Fs, manifest_paths: Vec<PathBuf>) -> Result<Vec<P
    let mut result = Vec::new();
    for path in &manifest_paths {
        let contents: Vec<u8> = fs.read_file(path).await?;
        if let Some(package) = read_package(path, &contents)? {
        if let Some(package) = Package::try_load_manifest(path, &contents)? {
            result.push(package);
        }
    }
@@ -337,79 +195,14 @@ fn batch_packages(packages: Vec<Package>) -> Result<Vec<PackageBatch>> {
mod tests {
    use super::*;
    use semver::Version;
    use std::path::PathBuf;

    fn version(version: &str) -> Version {
        Version::parse(version).unwrap()
    }

    #[test]
    fn read_package_success() {
        let manifest = br#"
            [package]
            name = "test"
            version = "1.2.0-preview"

            [build-dependencies]
            build_something = "1.3"
            local_build_something = { version = "0.2.0", path = "../local_build_something" }

            [dev-dependencies]
            dev_something = "1.1"
            local_dev_something = { version = "0.1.0", path = "../local_dev_something" }

            [dependencies]
            something = "1.0"
            local_something = { version = "1.1.3", path = "../local_something" }
        "#;
        let path: PathBuf = "test/Cargo.toml".into();

        let package = read_package(&path, manifest)
            .expect("parse success")
            .expect("is a package");
        assert_eq!("test", package.handle.name);
        assert_eq!(version("1.2.0-preview"), package.handle.version);

        let mut expected = BTreeSet::new();
        expected.insert(PackageHandle::new(
            "local_build_something",
            version("0.2.0"),
        ));
        expected.insert(PackageHandle::new("local_dev_something", version("0.1.0")));
        expected.insert(PackageHandle::new("local_something", version("1.1.3")));
        assert_eq!(expected, package.local_dependencies);
    }

    #[test]
    fn read_package_version_requirement_invalid() {
        let manifest = br#"
            [package]
            name = "test"
            version = "1.2.0-preview"

            [dependencies]
            local_something = { version = "1.0", path = "../local_something" }
        "#;
        let path: PathBuf = "test/Cargo.toml".into();

        let error = format!(
            "{}",
            read_package(&path, manifest).expect_err("should fail")
        );
        assert!(
            error.contains("Invalid crate version"),
            "'{}' should contain 'Invalid crate version'",
            error
        );
    }

    fn package(name: &str, dependencies: &[&str]) -> Package {
        Package::new(
            PackageHandle::new(name, Version::parse("1.0.0").unwrap()),
            PackageHandle::new(name, Version::parse("1.0.0").ok()),
            format!("{}/Cargo.toml", name),
            dependencies
                .iter()
                .map(|d| PackageHandle::new(*d, Version::parse("1.0.0").unwrap()))
                .map(|d| PackageHandle::new(*d, Version::parse("1.0.0").ok()))
                .collect(),
            Publish::Allowed,
        )
@@ -487,11 +280,11 @@ mod tests {

    fn pkg_ver(name: &str, version: &str, dependencies: &[(&str, &str)]) -> Package {
        Package::new(
            PackageHandle::new(name, Version::parse(version).unwrap()),
            PackageHandle::new(name, Some(Version::parse(version).unwrap())),
            format!("{}/Cargo.toml", name),
            dependencies
                .iter()
                .map(|p| PackageHandle::new(p.0, Version::parse(p.1).unwrap()))
                .map(|p| PackageHandle::new(p.0, Some(Version::parse(p.1).unwrap())))
                .collect(),
            Publish::Allowed,
        )
@@ -540,33 +333,21 @@ mod tests {
            package("aws-smithy-http-server-typescript", &[]),
        ];
        for pkg in server_packages {
            assert_eq!(
                [String::from("aws-sdk-rust-ci")]
                    .into_iter()
                    .collect::<HashSet<String>>(),
                pkg.expected_owners()
            );
            assert_eq!(&["aws-sdk-rust-ci"], pkg.expected_owners());
        }
    }

    #[test]
    fn test_expected_package_owners_sdk_crate() {
        let sdk_package = package("aws-types", &[]);
        assert_eq!(
            [String::from("aws-sdk-rust-ci")]
                .into_iter()
                .collect::<HashSet<String>>(),
            sdk_package.expected_owners()
        );
        assert_eq!(&["aws-sdk-rust-ci"], sdk_package.expected_owners());
    }

    #[test]
    fn test_expected_package_owners_smithy_runtime_crate() {
        let smithy_runtime_package = package("aws-smithy-types", &[]);
        assert_eq!(
            [String::from("aws-sdk-rust-ci")]
                .into_iter()
                .collect::<HashSet<String>>(),
            &["aws-sdk-rust-ci"],
            smithy_runtime_package.expected_owners()
        );
    }
+1 −2
Original line number Diff line number Diff line
@@ -4,13 +4,12 @@
 */

use crate::cargo;
use crate::package::PackageHandle;
use anyhow::Result;
use smithy_rs_tool_common::shell::ShellOperation;
use smithy_rs_tool_common::{
    index::CratesIndex,
    retry::{run_with_retry, BoxError, ErrorClass},
};
use smithy_rs_tool_common::{package::PackageHandle, shell::ShellOperation};
use std::time::Duration;
use std::{path::Path, sync::Arc};
use tracing::info;
Loading