mirror of https://github.com/smithy-lang/smithy-rs
Server SDK CHANGELOG.md file is created separately by the changelogger tool (#1513)
The affected target of a change (client, server, all) is shown in CHANGELOG.md The meta tag for a change log entry in CHANGELOG.next.toml supports adding the affected target, as an example: [smithy-rs] ... meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "server" } ... Possible values for target: [client, server, all]
This commit is contained in:
parent
e4d8dca25b
commit
9ede23b123
|
@ -29,7 +29,7 @@ pub const EXAMPLE_ENTRY: &str = r#"
|
|||
# [[smithy-rs]]
|
||||
# message = "Fix typos in module documentation for generated crates"
|
||||
# references = ["smithy-rs#920"]
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false, "sdk" = "client | server | all"}
|
||||
# author = "rcoh"
|
||||
"#;
|
||||
|
||||
|
@ -228,7 +228,13 @@ fn render_entry(entry: &HandAuthoredEntry, mut out: &mut String) {
|
|||
if !meta.is_empty() {
|
||||
meta.push(' ');
|
||||
}
|
||||
let mut references = entry.references.iter().map(to_md_link).collect::<Vec<_>>();
|
||||
let mut references = entry
|
||||
.meta
|
||||
.target
|
||||
.iter()
|
||||
.map(|t| t.to_string())
|
||||
.chain(entry.references.iter().map(to_md_link))
|
||||
.collect::<Vec<_>>();
|
||||
if !maintainers().contains(&entry.author.to_ascii_lowercase().as_str()) {
|
||||
references.push(format!("@{}", entry.author.to_ascii_lowercase()));
|
||||
};
|
||||
|
@ -263,6 +269,12 @@ fn load_changelogs(args: &RenderArgs) -> Result<Changelog> {
|
|||
for source in &args.source {
|
||||
let changelog = Changelog::load_from_file(source)
|
||||
.map_err(|errs| anyhow::Error::msg(format!("failed to load {source:?}: {errs:#?}")))?;
|
||||
changelog.validate().map_err(|errs| {
|
||||
anyhow::Error::msg(format!(
|
||||
"failed to load {source:?}: {errors}",
|
||||
errors = errs.join("\n")
|
||||
))
|
||||
})?;
|
||||
combined.merge(changelog);
|
||||
}
|
||||
Ok(combined)
|
||||
|
@ -434,6 +446,7 @@ mod test {
|
|||
date_based_release_metadata, render, version_based_release_metadata, Changelog,
|
||||
ChangelogEntries, ChangelogEntry,
|
||||
};
|
||||
use smithy_rs_tool_common::changelog::SdkAffected;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
fn render_full(entries: &[ChangelogEntry], release_header: &str) -> String {
|
||||
|
@ -460,6 +473,7 @@ references = ["smithy-rs#446"]
|
|||
author = "another-contrib"
|
||||
message = "I made a minor change"
|
||||
meta = { breaking = false, tada = false, bug = false }
|
||||
references = ["smithy-rs#200"]
|
||||
|
||||
[[aws-sdk-rust]]
|
||||
author = "rcoh"
|
||||
|
@ -502,7 +516,7 @@ version = "0.12.0"
|
|||
kind = "Feature"
|
||||
message = "Some API change"
|
||||
"#;
|
||||
let changelog: Changelog = toml::from_str(changelog_toml).expect("valid changelog");
|
||||
let changelog: Changelog = Changelog::parse_str(changelog_toml).expect("valid changelog");
|
||||
let ChangelogEntries {
|
||||
aws_sdk_rust,
|
||||
smithy_rs,
|
||||
|
@ -513,19 +527,19 @@ message = "Some API change"
|
|||
v0.3.0 (January 4th, 2022)
|
||||
==========================
|
||||
**Breaking Changes:**
|
||||
- ⚠ ([smithy-rs#445](https://github.com/awslabs/smithy-rs/issues/445)) I made a major change to update the code generator
|
||||
- ⚠ (all, [smithy-rs#445](https://github.com/awslabs/smithy-rs/issues/445)) I made a major change to update the code generator
|
||||
|
||||
**New this release:**
|
||||
- 🎉 ([smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446), @external-contrib) I made a change to update the code generator
|
||||
- 🎉 ([smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446), @external-contrib) I made a change to update the code generator
|
||||
- 🎉 (all, [smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446), @external-contrib) I made a change to update the code generator
|
||||
- 🎉 (all, [smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446), @external-contrib) I made a change to update the code generator
|
||||
|
||||
**Update guide:**
|
||||
blah blah
|
||||
- (@another-contrib) I made a minor change
|
||||
- (all, [smithy-rs#200](https://github.com/awslabs/smithy-rs/issues/200), @another-contrib) I made a minor change
|
||||
|
||||
**Contributors**
|
||||
Thank you for your contributions! ❤
|
||||
- @another-contrib
|
||||
- @another-contrib ([smithy-rs#200](https://github.com/awslabs/smithy-rs/issues/200))
|
||||
- @external-contrib ([smithy-rs#446](https://github.com/awslabs/smithy-rs/issues/446))
|
||||
"#
|
||||
.trim_start();
|
||||
|
@ -573,4 +587,70 @@ Thank you for your contributions! ❤
|
|||
assert_eq!("v0.11.0", result.tag);
|
||||
assert_eq!("some-other-manifest.json", result.manifest_name);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partition_client_server() {
|
||||
let sample = r#"
|
||||
[[smithy-rs]]
|
||||
author = "external-contrib"
|
||||
message = """
|
||||
this is a multiline
|
||||
message
|
||||
"""
|
||||
meta = { breaking = false, tada = true, bug = false, target = "server" }
|
||||
references = ["smithy-rs#446"]
|
||||
|
||||
[[aws-sdk-model]]
|
||||
module = "aws-sdk-s3"
|
||||
version = "0.14.0"
|
||||
kind = "Feature"
|
||||
message = "Some new API to do X"
|
||||
|
||||
[[smithy-rs]]
|
||||
author = "external-contrib"
|
||||
message = "a client message"
|
||||
meta = { breaking = false, tada = true, bug = false, target = "client" }
|
||||
references = ["smithy-rs#446"]
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "a change for both"
|
||||
meta = { breaking = false, tada = true, bug = false, target = "all" }
|
||||
references = ["smithy-rs#446"]
|
||||
author = "rcoh"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "a missing sdk meta"
|
||||
meta = { breaking = false, tada = true, bug = false }
|
||||
references = ["smithy-rs#446"]
|
||||
author = "rcoh"
|
||||
"#;
|
||||
let changelog: Changelog = Changelog::parse_str(sample).expect("valid changelog");
|
||||
let ChangelogEntries {
|
||||
aws_sdk_rust: _,
|
||||
smithy_rs,
|
||||
} = changelog.into();
|
||||
let affected = vec![
|
||||
SdkAffected::Server,
|
||||
SdkAffected::Client,
|
||||
SdkAffected::All,
|
||||
SdkAffected::All,
|
||||
];
|
||||
let entries = smithy_rs
|
||||
.iter()
|
||||
.filter_map(ChangelogEntry::hand_authored)
|
||||
.zip(affected)
|
||||
.collect::<Vec<_>>();
|
||||
for (e, a) in entries {
|
||||
assert_eq!(e.meta.target, Some(a));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_render() {
|
||||
let smithy_rs = Vec::<ChangelogEntry>::new();
|
||||
let (release_title, release_notes) = render(&smithy_rs, "some header");
|
||||
|
||||
assert_eq!(release_title, "some header\n===========\n");
|
||||
assert_eq!(release_notes, "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,8 @@ fn split_aws_sdk_test() {
|
|||
"meta": {
|
||||
"bug": false,
|
||||
"breaking": false,
|
||||
"tada": false
|
||||
"tada": false,
|
||||
"target": "all"
|
||||
},
|
||||
"author": "another-dev",
|
||||
"references": [
|
||||
|
@ -230,7 +231,7 @@ fn render_smithy_rs_test() {
|
|||
v0.42.0 (January 1st, 1970)
|
||||
===========================
|
||||
**New this release:**
|
||||
- ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change
|
||||
- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change
|
||||
|
||||
**Contributors**
|
||||
Thank you for your contributions! ❤
|
||||
|
@ -247,7 +248,7 @@ Old entry contents
|
|||
r#"{
|
||||
"tagName": "v0.42.0",
|
||||
"name": "v0.42.0 (January 1st, 1970)",
|
||||
"body": "**New this release:**\n- ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change\n\n**Contributors**\nThank you for your contributions! ❤\n- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))\n",
|
||||
"body": "**New this release:**\n- (all, [smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234), @another-dev) Another change\n\n**Contributors**\nThank you for your contributions! ❤\n- @another-dev ([smithy-rs#1234](https://github.com/awslabs/smithy-rs/issues/1234))\n",
|
||||
"prerelease": true
|
||||
}"#,
|
||||
release_manifest
|
||||
|
@ -347,3 +348,203 @@ Old entry contents
|
|||
release_manifest
|
||||
);
|
||||
}
|
||||
|
||||
/// entries with target set to each of the possible ones, and one entry with no target
|
||||
/// set, which should result in the default
|
||||
#[test]
|
||||
fn render_smithy_entries() {
|
||||
const NEXT_CHANGELOG: &'static str = r#"
|
||||
# Example changelog entries
|
||||
# [[aws-sdk-rust]]
|
||||
# message = "Fix typos in module documentation for generated crates"
|
||||
# references = ["smithy-rs#920"]
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
# author = "rcoh"
|
||||
#
|
||||
# [[smithy-rs]]
|
||||
# message = "Fix typos in module documentation for generated crates"
|
||||
# references = ["smithy-rs#920"]
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
# author = "rcoh"
|
||||
[[aws-sdk-rust]]
|
||||
message = "Some change"
|
||||
references = ["aws-sdk-rust#123", "smithy-rs#456"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = true }
|
||||
since-commit = "REPLACE_SINCE_COMMIT_1"
|
||||
author = "test-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "First change - server"
|
||||
references = ["smithy-rs#1"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "server" }
|
||||
author = "server-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Second change - should be all"
|
||||
references = ["smithy-rs#2"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "all" }
|
||||
author = "another-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Third change - empty"
|
||||
references = ["smithy-rs#3"]
|
||||
meta = { "breaking" = true, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Fourth change - client"
|
||||
references = ["smithy-rs#4"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
let tmp_dir = TempDir::new().unwrap();
|
||||
let source_path = tmp_dir.path().join("source.toml");
|
||||
let dest_path = tmp_dir.path().join("dest.md");
|
||||
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
|
||||
|
||||
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
|
||||
|
||||
fs::write(&source_path, NEXT_CHANGELOG).unwrap();
|
||||
fs::write(
|
||||
&dest_path,
|
||||
format!(
|
||||
"{}\nv0.41.0 (Some date in the past)\n=========\n\nOld entry contents\n",
|
||||
USE_UPDATE_CHANGELOGS
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(&release_manifest_path, "overwrite-me").unwrap();
|
||||
|
||||
subcommand_render(&RenderArgs {
|
||||
change_set: ChangeSet::SmithyRs,
|
||||
independent_versioning: false,
|
||||
source: vec![source_path.clone()],
|
||||
source_to_truncate: source_path.clone(),
|
||||
changelog_output: dest_path.clone(),
|
||||
release_manifest_output: Some(tmp_dir.path().into()),
|
||||
date_override: Some(OffsetDateTime::UNIX_EPOCH),
|
||||
previous_release_versions_manifest: None,
|
||||
smithy_rs_location: Some(tmp_dir.path().into()),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let source = fs::read_to_string(&source_path).unwrap();
|
||||
let dest = fs::read_to_string(&dest_path).unwrap();
|
||||
|
||||
// source file should be empty
|
||||
pretty_assertions::assert_str_eq!(EXAMPLE_ENTRY.trim(), source);
|
||||
pretty_assertions::assert_str_eq!(
|
||||
r#"<!-- Do not manually edit this file. Use the `changelogger` tool. -->
|
||||
v0.42.0 (January 1st, 1970)
|
||||
===========================
|
||||
**Breaking Changes:**
|
||||
- ⚠ (all, [smithy-rs#3](https://github.com/awslabs/smithy-rs/issues/3)) Third change - empty
|
||||
|
||||
**New this release:**
|
||||
- (server, [smithy-rs#1](https://github.com/awslabs/smithy-rs/issues/1), @server-dev) First change - server
|
||||
- (all, [smithy-rs#2](https://github.com/awslabs/smithy-rs/issues/2), @another-dev) Second change - should be all
|
||||
- (client, [smithy-rs#4](https://github.com/awslabs/smithy-rs/issues/4)) Fourth change - client
|
||||
|
||||
**Contributors**
|
||||
Thank you for your contributions! ❤
|
||||
- @another-dev ([smithy-rs#2](https://github.com/awslabs/smithy-rs/issues/2))
|
||||
- @server-dev ([smithy-rs#1](https://github.com/awslabs/smithy-rs/issues/1))
|
||||
|
||||
v0.41.0 (Some date in the past)
|
||||
=========
|
||||
|
||||
Old entry contents
|
||||
"#,
|
||||
dest
|
||||
);
|
||||
}
|
||||
|
||||
/// aws_sdk_rust should not be allowed to have target entries
|
||||
#[test]
|
||||
fn aws_sdk_cannot_have_target() {
|
||||
const NEXT_CHANGELOG: &'static str = r#"
|
||||
# Example changelog entries
|
||||
# [[aws-sdk-rust]]
|
||||
# message = "Fix typos in module documentation for generated crates"
|
||||
# references = ["smithy-rs#920"]
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
# author = "rcoh"
|
||||
#
|
||||
# [[smithy-rs]]
|
||||
# message = "Fix typos in module documentation for generated crates"
|
||||
# references = ["smithy-rs#920"]
|
||||
# meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
# author = "rcoh"
|
||||
[[aws-sdk-rust]]
|
||||
message = "Some change"
|
||||
references = ["aws-sdk-rust#123", "smithy-rs#456"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
|
||||
since-commit = "REPLACE_SINCE_COMMIT_1"
|
||||
author = "test-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "First change - server"
|
||||
references = ["smithy-rs#1"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "server" }
|
||||
author = "server-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Second change - should be all"
|
||||
references = ["smithy-rs#2"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, target = "all" }
|
||||
author = "another-dev"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Third change - empty"
|
||||
references = ["smithy-rs#3"]
|
||||
meta = { "breaking" = true, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Fourth change - client"
|
||||
references = ["smithy-rs#4"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
let tmp_dir = TempDir::new().unwrap();
|
||||
let source_path = tmp_dir.path().join("source.toml");
|
||||
let dest_path = tmp_dir.path().join("dest.md");
|
||||
let release_manifest_path = tmp_dir.path().join("smithy-rs-release-manifest.json");
|
||||
|
||||
create_fake_repo_root(tmp_dir.path(), "0.42.0", "0.12.0");
|
||||
|
||||
fs::write(&source_path, NEXT_CHANGELOG).unwrap();
|
||||
fs::write(
|
||||
&dest_path,
|
||||
format!(
|
||||
"{}\nv0.41.0 (Some date in the past)\n=========\n\nOld entry contents\n",
|
||||
USE_UPDATE_CHANGELOGS
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(&release_manifest_path, "overwrite-me").unwrap();
|
||||
|
||||
let result = subcommand_render(&RenderArgs {
|
||||
change_set: ChangeSet::SmithyRs,
|
||||
independent_versioning: false,
|
||||
source: vec![source_path.clone()],
|
||||
source_to_truncate: source_path.clone(),
|
||||
changelog_output: dest_path.clone(),
|
||||
release_manifest_output: Some(tmp_dir.path().into()),
|
||||
date_override: Some(OffsetDateTime::UNIX_EPOCH),
|
||||
previous_release_versions_manifest: None,
|
||||
smithy_rs_location: Some(tmp_dir.path().into()),
|
||||
});
|
||||
|
||||
if let Err(e) = result {
|
||||
let index = e
|
||||
.to_string()
|
||||
.find("aws-sdk-rust changelog entry cannot have an affected target");
|
||||
assert!(index.is_some());
|
||||
} else {
|
||||
assert!(
|
||||
false,
|
||||
"This should have been error that aws-sdk-rust has a target entry"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,68 @@
|
|||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
use std::fmt;
|
||||
use std::fmt::{self, Display};
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, PartialEq, Eq)]
|
||||
pub enum SdkAffected {
|
||||
#[serde(rename = "client")]
|
||||
Client,
|
||||
#[serde(rename = "server")]
|
||||
Server,
|
||||
#[serde(rename = "all")]
|
||||
All,
|
||||
}
|
||||
|
||||
impl Default for SdkAffected {
|
||||
fn default() -> Self {
|
||||
SdkAffected::All
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SdkAffected {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SdkAffected::Client => write!(f, "client"),
|
||||
SdkAffected::Server => write!(f, "server"),
|
||||
SdkAffected::All => write!(f, "all"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for SdkAffected {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(sdk: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match sdk.to_lowercase().as_str() {
|
||||
"client" => Ok(SdkAffected::Client),
|
||||
"server" => Ok(SdkAffected::Server),
|
||||
"all" => Ok(SdkAffected::All),
|
||||
_ => bail!("An invalid type of SDK type {sdk} has been mentioned in the meta tags"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// allow incase sensitive comparison of enum variants
|
||||
impl<'de> Deserialize<'de> for SdkAffected {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
FromStr::from_str(&s).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Meta {
|
||||
pub bug: bool,
|
||||
pub breaking: bool,
|
||||
pub tada: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub target: Option<SdkAffected>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -143,8 +196,9 @@ impl Changelog {
|
|||
self.sdk_models.extend(other.sdk_models.into_iter());
|
||||
}
|
||||
|
||||
fn parse_str(value: &str) -> Result<Changelog> {
|
||||
match toml::from_str(value).context("Invalid TOML changelog format") {
|
||||
pub fn parse_str(value: &str) -> Result<Changelog> {
|
||||
let mut changelog: Changelog =
|
||||
(match toml::from_str(value).context("Invalid TOML changelog format") {
|
||||
Ok(parsed) => Ok(parsed),
|
||||
Err(toml_err) => {
|
||||
// Remove comments from the top
|
||||
|
@ -163,8 +217,15 @@ impl Changelog {
|
|||
),
|
||||
}
|
||||
}
|
||||
} as Result<Changelog>)?;
|
||||
// all smithry-rs entries should have meta.target set to the default value instead of None
|
||||
for entry in &mut changelog.smithy_rs {
|
||||
if entry.meta.target.is_none() {
|
||||
entry.meta.target = Some(SdkAffected::default());
|
||||
}
|
||||
}
|
||||
Ok(changelog)
|
||||
}
|
||||
|
||||
pub fn load_from_file(path: impl AsRef<Path>) -> Result<Changelog> {
|
||||
let contents = std::fs::read_to_string(path.as_ref())
|
||||
|
@ -177,12 +238,30 @@ impl Changelog {
|
|||
}
|
||||
|
||||
pub fn validate(&self) -> Result<(), Vec<String>> {
|
||||
let mut errors = vec![];
|
||||
for entry in self.aws_sdk_rust.iter().chain(self.smithy_rs.iter()) {
|
||||
if let Err(e) = entry.validate() {
|
||||
errors.push(format!("{}", e));
|
||||
let validate_aws_handauthored = |entry: &HandAuthoredEntry| -> Result<()> {
|
||||
entry.validate()?;
|
||||
if entry.meta.target.is_some() {
|
||||
bail!("aws-sdk-rust changelog entry cannot have an affected target");
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let validate_smithyrs_handauthored = |entry: &HandAuthoredEntry| -> Result<()> {
|
||||
entry.validate()?;
|
||||
if entry.meta.target.is_none() {
|
||||
bail!("smithy-rs entry must have an affected target");
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let errors: Vec<_> = self
|
||||
.aws_sdk_rust
|
||||
.iter()
|
||||
.map(validate_aws_handauthored)
|
||||
.chain(self.smithy_rs.iter().map(validate_smithyrs_handauthored))
|
||||
.filter_map(Result::err)
|
||||
.map(|e| format!("{}", e))
|
||||
.collect();
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -193,7 +272,8 @@ impl Changelog {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Changelog;
|
||||
use super::{Changelog, HandAuthoredEntry, SdkAffected};
|
||||
use anyhow::Context;
|
||||
|
||||
#[test]
|
||||
fn parse_json() {
|
||||
|
@ -240,4 +320,186 @@ mod tests {
|
|||
assert_eq!(1, changelog.sdk_models.len());
|
||||
assert_eq!("Some API change", changelog.sdk_models[0].message);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_are_combined() {
|
||||
let buffer = r#"
|
||||
[[aws-sdk-rust]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = ""
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = ""
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "fz"
|
||||
"#;
|
||||
// three errors should be produced, missing authors x 2 and a SdkAffected is not set to default
|
||||
let changelog: Changelog = toml::from_str(buffer).expect("valid changelog");
|
||||
let res = changelog.validate();
|
||||
assert!(res.is_err());
|
||||
if let Err(e) = res {
|
||||
assert_eq!(e.len(), 3);
|
||||
assert!(e.contains(&"smithy-rs entry must have an affected target".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn confirm_smithy_rs_defaults_set() {
|
||||
let buffer = r#"
|
||||
[[aws-sdk-rust]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "fz"
|
||||
"#;
|
||||
{
|
||||
// loading directly from toml::from_str won't set the default target field
|
||||
let changelog: Changelog = toml::from_str(buffer).expect("valid changelog");
|
||||
let res = changelog.validate();
|
||||
assert!(res.is_err());
|
||||
if let Err(e) = res {
|
||||
assert!(e.contains(&"smithy-rs entry must have an affected target".to_string()))
|
||||
}
|
||||
}
|
||||
{
|
||||
// loading through Chanelog will result in no error
|
||||
let changelog: Changelog = Changelog::parse_str(buffer).expect("valid changelog");
|
||||
let res = changelog.validate();
|
||||
assert!(res.is_ok());
|
||||
if let Err(e) = res {
|
||||
assert!(false, "some error has been produced {e:?}");
|
||||
}
|
||||
assert_eq!(changelog.smithy_rs[1].meta.target, Some(SdkAffected::All));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_smithy_ok() {
|
||||
// by default smithy-rs meta data should say change is for both
|
||||
let toml = r#"
|
||||
[[aws-sdk-rust]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "server" }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
|
||||
author = "rcoh"
|
||||
[[smithy-rs]]
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
let changelog = Changelog::parse_str(toml).unwrap();
|
||||
assert_eq!(changelog.smithy_rs.len(), 4);
|
||||
assert_eq!(
|
||||
changelog.smithy_rs[0].meta.target,
|
||||
Some(SdkAffected::Client)
|
||||
);
|
||||
assert_eq!(
|
||||
changelog.smithy_rs[1].meta.target,
|
||||
Some(SdkAffected::Server)
|
||||
);
|
||||
assert_eq!(changelog.smithy_rs[2].meta.target, Some(SdkAffected::All));
|
||||
assert_eq!(changelog.smithy_rs[3].meta.target, Some(SdkAffected::All));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hand_authored_sdk() {
|
||||
// server target
|
||||
let value = r#"
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Server" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
{
|
||||
let value: HandAuthoredEntry = toml::from_str(value)
|
||||
.context("String should have parsed")
|
||||
.unwrap();
|
||||
assert_eq!(value.meta.target, Some(SdkAffected::Server));
|
||||
}
|
||||
|
||||
// client target
|
||||
let value = r#"
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Client" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
{
|
||||
let value: HandAuthoredEntry = toml::from_str(value)
|
||||
.context("String should have parsed")
|
||||
.unwrap();
|
||||
assert_eq!(value.meta.target, Some(SdkAffected::Client));
|
||||
}
|
||||
// Both target
|
||||
let value = r#"
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
{
|
||||
let value: HandAuthoredEntry = toml::from_str(value)
|
||||
.context("String should have parsed")
|
||||
.unwrap();
|
||||
assert_eq!(value.meta.target, Some(SdkAffected::All));
|
||||
}
|
||||
// an invalid sdk value
|
||||
let value = r#"
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "Some other invalid" }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
{
|
||||
let value: Result<HandAuthoredEntry, _> =
|
||||
toml::from_str(value).context("String should not have parsed");
|
||||
assert!(value.is_err());
|
||||
}
|
||||
// missing sdk in the meta tag
|
||||
let value = r#"
|
||||
message = "Fix typos in module documentation for generated crates"
|
||||
references = ["smithy-rs#920"]
|
||||
meta = { "breaking" = false, "tada" = false, "bug" = false }
|
||||
author = "rcoh"
|
||||
"#;
|
||||
{
|
||||
let value: HandAuthoredEntry = toml::from_str(value)
|
||||
.context("String should have parsed as it has none meta.sdk")
|
||||
.unwrap();
|
||||
assert_eq!(value.meta.target, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue