mirror of https://github.com/smithy-lang/smithy-rs
Support unchanging versions in the versioner (#3414)
## Motivation and Context The nested path dependencies in our generated runtime crates cause issues when simulating a release. This strips those out in order to support testing a release where some versions _don't_ change. ## Testing https://github.com/smithy-lang/smithy-rs/actions/runs/7917462892 ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
This commit is contained in:
parent
1ea9d055f0
commit
30421e1333
|
@ -148,6 +148,16 @@ version = "1.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_toml"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3dc9f7a067415ab5058020f04c60ec7b557084dbec0e021217bbabc7a8d38d14"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"toml 0.8.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.83"
|
version = "1.0.83"
|
||||||
|
@ -903,6 +913,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"camino",
|
"camino",
|
||||||
|
"cargo_toml",
|
||||||
"clap",
|
"clap",
|
||||||
"crates-index",
|
"crates-index",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
|
@ -911,6 +922,7 @@ dependencies = [
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"test-common",
|
"test-common",
|
||||||
"toml 0.5.11",
|
"toml 0.5.11",
|
||||||
|
"toml_edit 0.22.5",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
@ -1276,7 +1288,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit",
|
"toml_edit 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1298,7 +1310,18 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow",
|
"winnow 0.5.28",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99e68c159e8f5ba8a28c4eb7b0c0c190d77bb479047ca713270048145a9ad28a"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.1.0",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow 0.6.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1684,6 +1707,15 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d90f4e0f530c4c69f62b80d839e9ef3855edc9cba471a160c4d692deed62b401"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.50.0"
|
version = "0.50.0"
|
||||||
|
|
|
@ -25,6 +25,9 @@ tempfile = "3.9.0"
|
||||||
toml = { version = "0.5.8", features = ["preserve_order"] }
|
toml = { version = "0.5.8", features = ["preserve_order"] }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
# why both? cargo_toml can't write out to a file because of a toml_rs longstanding issue/bug
|
||||||
|
cargo_toml = "0.19.0"
|
||||||
|
toml_edit = "0.22"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-common = { path = "./test-common" }
|
test-common = { path = "./test-common" }
|
||||||
|
|
|
@ -10,9 +10,11 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use camino::Utf8Path;
|
use camino::Utf8Path;
|
||||||
|
use cargo_toml::Manifest;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use smithy_rs_tool_common::command::sync::CommandExt;
|
use smithy_rs_tool_common::command::sync::CommandExt;
|
||||||
use std::{fs, time::Duration};
|
use std::{fs, time::Duration};
|
||||||
|
use toml_edit::Document;
|
||||||
|
|
||||||
pub fn patch(args: PatchRuntime) -> Result<()> {
|
pub fn patch(args: PatchRuntime) -> Result<()> {
|
||||||
let smithy_rs = step("Resolving smithy-rs", || {
|
let smithy_rs = step("Resolving smithy-rs", || {
|
||||||
|
@ -22,6 +24,11 @@ pub fn patch(args: PatchRuntime) -> Result<()> {
|
||||||
bail!("smithy-rs has a dirty working tree. Aborting.");
|
bail!("smithy-rs has a dirty working tree. Aborting.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let aws_sdk_rust = step("Resolving aws-sdk-rust", || Repo::new(Some(&args.sdk_path)))?;
|
||||||
|
if is_dirty(&aws_sdk_rust)? {
|
||||||
|
bail!("aws-sdk-rust has a dirty working tree. Aborting.");
|
||||||
|
}
|
||||||
|
|
||||||
step(
|
step(
|
||||||
"Patching smithy-rs/gradle.properties with given crate version numbers",
|
"Patching smithy-rs/gradle.properties with given crate version numbers",
|
||||||
|| patch_gradle_properties(&smithy_rs, &args),
|
|| patch_gradle_properties(&smithy_rs, &args),
|
||||||
|
@ -76,7 +83,9 @@ pub fn patch_with(args: PatchRuntimeWith) -> Result<()> {
|
||||||
apply_version_only_dependencies(&aws_sdk_rust)
|
apply_version_only_dependencies(&aws_sdk_rust)
|
||||||
})?;
|
})?;
|
||||||
step("Patching aws-sdk-rust root Cargo.toml", || {
|
step("Patching aws-sdk-rust root Cargo.toml", || {
|
||||||
patch_workspace_cargo_toml(&aws_sdk_rust, &args.runtime_crate_path)
|
let crates_to_patch =
|
||||||
|
remove_unchanged_dependencies(&aws_sdk_rust, &args.runtime_crate_path)?;
|
||||||
|
patch_workspace_cargo_toml(&aws_sdk_rust, &args.runtime_crate_path, crates_to_patch)
|
||||||
})?;
|
})?;
|
||||||
step("Running cargo update", || {
|
step("Running cargo update", || {
|
||||||
aws_sdk_rust
|
aws_sdk_rust
|
||||||
|
@ -127,27 +136,46 @@ fn apply_version_only_dependencies(aws_sdk_rust: &Repo) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn patch_workspace_cargo_toml(aws_sdk_rust: &Repo, runtime_crate_path: &Utf8Path) -> Result<()> {
|
/// Determine if a given crate has a new version vs. the release we're comparing
|
||||||
let crates_to_patch = fs::read_dir(runtime_crate_path)
|
fn crate_version_has_changed(
|
||||||
.context(format!(
|
crate_name: &str,
|
||||||
"could list crates in directory {:?}",
|
aws_sdk_rust: &Repo,
|
||||||
runtime_crate_path
|
runtime_crate_path: &Utf8Path,
|
||||||
))?
|
) -> Result<bool> {
|
||||||
.map(|dir| dir.unwrap().file_name())
|
let sdk_cargo_toml = aws_sdk_rust
|
||||||
.map(|osstr| osstr.into_string().expect("invalid utf-8 directory"))
|
.root
|
||||||
.filter(|name| name.starts_with("aws-"))
|
.join("sdk")
|
||||||
.collect::<Vec<_>>();
|
.join(crate_name)
|
||||||
|
.join("Cargo.toml");
|
||||||
|
let to_patch_cargo_toml = runtime_crate_path.join(crate_name).join("Cargo.toml");
|
||||||
|
assert!(
|
||||||
|
sdk_cargo_toml.exists(),
|
||||||
|
"{:?} did not exist!",
|
||||||
|
sdk_cargo_toml
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
to_patch_cargo_toml.exists(),
|
||||||
|
"{:?} did not exist!",
|
||||||
|
to_patch_cargo_toml
|
||||||
|
);
|
||||||
|
let sdk_cargo_toml = Manifest::from_path(sdk_cargo_toml).context("could not parse")?;
|
||||||
|
let to_patch_toml = Manifest::from_path(to_patch_cargo_toml).context("could not parse")?;
|
||||||
|
Ok(sdk_cargo_toml.package().version() != to_patch_toml.package().version())
|
||||||
|
}
|
||||||
|
fn patch_workspace_cargo_toml(
|
||||||
|
aws_sdk_rust: &Repo,
|
||||||
|
runtime_crate_path: &Utf8Path,
|
||||||
|
crates_to_patch: impl Iterator<Item = String>,
|
||||||
|
) -> Result<()> {
|
||||||
let patch_sections = crates_to_patch
|
let patch_sections = crates_to_patch
|
||||||
.iter()
|
.map(|crate_name| {
|
||||||
.map(|crte| {
|
let path = runtime_crate_path.join(&crate_name);
|
||||||
let path = runtime_crate_path.join(crte);
|
|
||||||
assert!(
|
assert!(
|
||||||
path.exists(),
|
path.exists(),
|
||||||
"tried to reference a crate that did not exist!"
|
"tried to reference a crate that did not exist!"
|
||||||
);
|
);
|
||||||
format!(
|
format!(
|
||||||
"{crte} = {{ path = '{}' }}",
|
"{crate_name} = {{ path = '{}' }}",
|
||||||
path.canonicalize_utf8().unwrap()
|
path.canonicalize_utf8().unwrap()
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -164,6 +192,77 @@ fn patch_workspace_cargo_toml(aws_sdk_rust: &Repo, runtime_crate_path: &Utf8Path
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes Path dependencies referring to unchanged crates & returns a list of crates to patch
|
||||||
|
fn remove_unchanged_dependencies(
|
||||||
|
aws_sdk_rust: &Repo,
|
||||||
|
runtime_crate_path: &Utf8Path,
|
||||||
|
) -> Result<impl Iterator<Item = String>> {
|
||||||
|
let all_crates = fs::read_dir(runtime_crate_path)
|
||||||
|
.context(format!(
|
||||||
|
"could list crates in directory {:?}",
|
||||||
|
runtime_crate_path
|
||||||
|
))?
|
||||||
|
.map(|dir| dir.unwrap().file_name())
|
||||||
|
.map(|osstr| osstr.into_string().expect("invalid utf-8 directory"))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let (crates_to_patch, unchanged_crates): (Vec<_>, Vec<_>) =
|
||||||
|
all_crates.clone().into_iter().partition(|crate_dir| {
|
||||||
|
crate_version_has_changed(crate_dir, aws_sdk_rust, runtime_crate_path)
|
||||||
|
.expect("failed to determine change-status")
|
||||||
|
});
|
||||||
|
|
||||||
|
for patched_crate in &all_crates {
|
||||||
|
remove_unchanged_path_dependencies(runtime_crate_path, &unchanged_crates, patched_crate)?;
|
||||||
|
}
|
||||||
|
Ok(crates_to_patch
|
||||||
|
.into_iter()
|
||||||
|
.filter(|crte| crte.starts_with("aws-")))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove `path = ...` from the dependency section for unchanged crates
|
||||||
|
///
|
||||||
|
/// If we leave these path dependencies in, we'll get an error when we try to patch because the
|
||||||
|
/// version numbers are the same.
|
||||||
|
fn remove_unchanged_path_dependencies(
|
||||||
|
runtime_crate_path: &Utf8Path,
|
||||||
|
unchanged_crates: &[String],
|
||||||
|
patched_crate: &String,
|
||||||
|
) -> Result<()> {
|
||||||
|
let path = runtime_crate_path.join(patched_crate).join("Cargo.toml");
|
||||||
|
let manifest = Manifest::from_path(&path)?;
|
||||||
|
let mut mutable_manifest = fs::read_to_string(&path)
|
||||||
|
.context("failed to read file")
|
||||||
|
.context(path.clone())?
|
||||||
|
.parse::<Document>()
|
||||||
|
.context("invalid toml in manifest!")?;
|
||||||
|
let mut updates = false;
|
||||||
|
let sections = [
|
||||||
|
(manifest.dependencies, "dependencies"),
|
||||||
|
(manifest.dev_dependencies, "dev-dependencies"),
|
||||||
|
];
|
||||||
|
for (deps_set, key) in sections {
|
||||||
|
for (dependency_name, dependency_metadata) in deps_set.iter() {
|
||||||
|
if unchanged_crates.iter().any(|crate_name| {
|
||||||
|
crate_name.as_str()
|
||||||
|
== dependency_metadata
|
||||||
|
.package()
|
||||||
|
.unwrap_or(dependency_name.as_str())
|
||||||
|
}) {
|
||||||
|
mutable_manifest[key][dependency_name]
|
||||||
|
.as_table_mut()
|
||||||
|
.unwrap()
|
||||||
|
.remove("path");
|
||||||
|
updates = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if updates {
|
||||||
|
fs::write(&path, mutable_manifest.to_string()).context("failed to write back manifest")?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn is_dirty(repo: &Repo) -> Result<bool> {
|
fn is_dirty(repo: &Repo) -> Result<bool> {
|
||||||
let result = repo
|
let result = repo
|
||||||
.git(["status", "--porcelain"])
|
.git(["status", "--porcelain"])
|
||||||
|
|
Loading…
Reference in New Issue