Unified · Split
| @@ -6,7 +6,7 @@ mod init; · 5 unmodified lines | ||
| 6 | 6 | mod merge; |
| 7 | 7 | mod parse; |
| 8 | 8 | pub mod section; |
| 9 | −mod write; | |
| 9 | +pub mod write; | |
| 10 | 10 | |
| 11 | 11 | #[derive(PartialEq, Eq, Debug, Clone)] |
| 12 | 12 | pub enum Section { |
| @@ -19,12 +19,24 @@ impl std::fmt::Display for changelog::Version { · 18 unmodified lines | ||
| 19 | 19 | } |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | +/// Define how linkable items should be written | |
| 23 | +#[derive(Clone)] | |
| 24 | +pub enum Linkables { | |
| 25 | + /// Use markdown links to link directly to the linkable items | |
| 26 | + AsLinks { | |
| 27 | + /// The location of the repository to link to, without trailing slash | |
| 28 | + repository_url: String, | |
| 29 | + }, | |
| 30 | + /// Leave them in a textual representation for the hosting platform to auto-link them | |
| 31 | + AsText, | |
| 32 | +} | |
| 33 | + | |
| 22 | 34 | impl Section { |
| 23 | 35 | pub const UNKNOWN_TAG_START: &'static str = "<csr-unknown>"; |
| 24 | 36 | pub const UNKNOWN_TAG_END: &'static str = "<csr-unknown/>"; |
| 25 | 37 | pub const READONLY_TAG: &'static str = "<csr-read-only-do-not-edit/>\n"; // needs a newline to not interfere with formatting |
| 26 | 38 | |
| 27 | − pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { | |
| 39 | + pub fn write_to(&self, mut out: impl std::io::Write, link_mode: &Linkables) -> std::io::Result<()> { | |
| 28 | 40 | match self { |
| 29 | 41 | Section::Verbatim { text, .. } => out.write_all(text.as_bytes()), |
| 30 | 42 | Section::Release { |
| @@ -55,7 +67,7 @@ impl Section { · 24 unmodified lines | ||
| 55 | 67 | |
| 56 | 68 | let section_level = *heading_level + 1; |
| 57 | 69 | for segment in segments { |
| 58 | − segment.write_to(section_level, &mut out)?; | |
| 70 | + segment.write_to(section_level, link_mode, &mut out)?; | |
| 59 | 71 | } |
| 60 | 72 | if !unknown.is_empty() { |
| 61 | 73 | writeln!(out, "{}", Section::UNKNOWN_TAG_START)?; |
| @@ -73,16 +85,21 @@ fn heading(level: usize) -> String { · 11 unmodified lines | ||
| 73 | 85 | } |
| 74 | 86 | |
| 75 | 87 | impl ChangeLog { |
| 76 | − pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { | |
| 88 | + pub fn write_to(&self, mut out: impl std::io::Write, link_mode: &Linkables) -> std::io::Result<()> { | |
| 77 | 89 | for section in &self.sections { |
| 78 | − section.write_to(&mut out)?; | |
| 90 | + section.write_to(&mut out, link_mode)?; | |
| 79 | 91 | } |
| 80 | 92 | Ok(()) |
| 81 | 93 | } |
| 82 | 94 | } |
| 83 | 95 | |
| 84 | 96 | impl section::Segment { |
| 85 | − pub fn write_to(&self, section_level: usize, mut out: impl std::io::Write) -> std::io::Result<()> { | |
| 97 | + pub fn write_to( | |
| 98 | + &self, | |
| 99 | + section_level: usize, | |
| 100 | + _link_mode: &Linkables, | |
| 101 | + mut out: impl std::io::Write, | |
| 102 | + ) -> std::io::Result<()> { | |
| 86 | 103 | match self { |
| 87 | 104 | Segment::User { markdown } => out.write_all(markdown.as_bytes())?, |
| 88 | 105 | Segment::Conventional(segment::Conventional { |
| @@ -1,3 +1,4 @@ | ||
| 1 | +use crate::changelog::write::Linkables; | |
| 1 | 2 | use crate::{bat, command::changelog::Options, git, utils::will, ChangeLog}; |
| 2 | 3 | |
| 3 | 4 | pub fn changelog(opts: Options, crates: Vec<String>) -> anyhow::Result<()> { |
| @@ -33,7 +34,16 @@ pub fn changelog(opts: Options, crates: Vec<String>) -> anyhow::Result<()> { · 29 unmodified lines | ||
| 33 | 34 | .expect("contained in workspace") |
| 34 | 35 | .display() |
| 35 | 36 | ); |
| 36 | − lock.with_mut(|file| log.write_to(file))?; | |
| 37 | + lock.with_mut(|file| { | |
| 38 | + log.write_to( | |
| 39 | + file, | |
| 40 | + &if opts.dry_run { | |
| 41 | + Linkables::AsText | |
| 42 | + } else { | |
| 43 | + Linkables::AsText // TODO: figure out repo url | |
| 44 | + }, | |
| 45 | + ) | |
| 46 | + })?; | |
| 37 | 47 | if let Some(bat) = bat.as_ref() { |
| 38 | 48 | bat.display_to_tty(lock.lock_path())?; |
| 39 | 49 | } |
| @@ -86,7 +86,7 @@ pub(in crate::command::release_impl) fn edit_version_and_fixup_dependent_crates_ · 85 unmodified lines | ||
| 86 | 86 | if !recent_release_in_log.is_essential() { |
| 87 | 87 | empty_changelogs_for_current_version.push(pending_changelog_changes.len()); |
| 88 | 88 | } |
| 89 | − lock.with_mut(|file| log.write_to(file))?; | |
| 89 | + lock.with_mut(|file| log.write_to(file, &changelog::write::Linkables::AsText))?; // TODO: use repo url | |
| 90 | 90 | pending_changelog_changes.push((publishee, changed_relevant_content, lock)); |
| 91 | 91 | } |
| 92 | 92 | } |
| @@ -45,21 +45,28 @@ fn conventional_write_empty_messages() -> Result { · 44 unmodified lines | ||
| 45 | 45 | }], |
| 46 | 46 | }; |
| 47 | 47 | |
| 48 | − for _round in 1..=2 { | |
| 49 | − let mut buf = Vec::<u8>::new(); | |
| 50 | − log.write_to(&mut buf)?; | |
| 51 | − let md = buf.to_str()?; | |
| 52 | − insta::assert_snapshot!(md); | |
| 48 | + for link_mode in &[ | |
| 49 | + changelog::write::Linkables::AsText, | |
| 50 | + changelog::write::Linkables::AsLinks { | |
| 51 | + repository_url: "https://github.com/user/repo".into(), | |
| 52 | + }, | |
| 53 | + ] { | |
| 54 | + for _round in 1..=2 { | |
| 55 | + let mut buf = Vec::<u8>::new(); | |
| 56 | + log.write_to(&mut buf, link_mode)?; | |
| 57 | + let md = buf.to_str()?; | |
| 58 | + insta::assert_snapshot!(md); | |
| 53 | 59 | |
| 54 | − let parsed_log = ChangeLog::from_markdown(md); | |
| 55 | − assert_eq!(parsed_log, log, "we can parse this back losslessly"); | |
| 60 | + let parsed_log = ChangeLog::from_markdown(md); | |
| 61 | + assert_eq!(parsed_log, log, "we can parse this back losslessly"); | |
| 62 | + } | |
| 56 | 63 | } |
| 57 | 64 | Ok(()) |
| 58 | 65 | } |
| 59 | 66 | |
| 60 | 67 | #[test] |
| 61 | 68 | fn all_section_types_round_trips_lossy() -> Result { |
| 62 | − let mut log = ChangeLog { | |
| 69 | + let log = ChangeLog { | |
| 63 | 70 | sections: vec![ |
| 64 | 71 | Section::Verbatim { |
| 65 | 72 | text: "# Changelog\n\nmy very own header\n\n".into(), |
| @@ -130,16 +137,21 @@ fn all_section_types_round_trips_lossy() -> Result { · 64 unmodified lines | ||
| 130 | 137 | }, |
| 131 | 138 | ], |
| 132 | 139 | }; |
| 133 | − for _round in 0..1 { | |
| 140 | + | |
| 141 | + for link_mode in &[ | |
| 142 | + changelog::write::Linkables::AsText, | |
| 143 | + changelog::write::Linkables::AsLinks { | |
| 144 | + repository_url: "https://github.com/user/repo".into(), | |
| 145 | + }, | |
| 146 | + ] { | |
| 134 | 147 | // NOTE: we can't run this a second time as the statistical information will be gone (it was never parsed back) |
| 135 | 148 | let mut buf = Vec::<u8>::new(); |
| 136 | − log.write_to(&mut buf)?; | |
| 149 | + log.write_to(&mut buf, link_mode)?; | |
| 137 | 150 | let md = buf.to_str()?; |
| 138 | 151 | insta::assert_snapshot!(md); |
| 139 | 152 | |
| 140 | 153 | let parsed_log = ChangeLog::from_markdown(md); |
| 141 | 154 | assert_eq!(parsed_log, log, "we must be able to parse the exact input back"); |
| 142 | − log = parsed_log; | |
| 143 | 155 | } |
| 144 | 156 | Ok(()) |
| 145 | 157 | } |
| @@ -0,0 +1,48 @@ | ||
| 1 | +--- | |
| 2 | +source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs | |
| 3 | +expression: md | |
| 4 | + | |
| 5 | +--- | |
| 6 | +# Changelog | |
| 7 | + | |
| 8 | +my very own header | |
| 9 | + | |
| 10 | +## Unreleased | |
| 11 | + | |
| 12 | +<csr-unknown> | |
| 13 | +hello | |
| 14 | +world | |
| 15 | +<csr-unknown/> | |
| 16 | +#### v1.0.2-beta.2 (1970-01-01) | |
| 17 | + | |
| 18 | +* hello world | |
| 19 | + this | |
| 20 | +##### Thanks Clippy | |
| 21 | + | |
| 22 | +<csr-read-only-do-not-edit/> | |
| 23 | + | |
| 24 | +[Clippy](https://github.com/rust-lang/rust-clippy) helped 42 times to make code idiomatic. | |
| 25 | + | |
| 26 | +##### Commit Statistics | |
| 27 | + | |
| 28 | +<csr-read-only-do-not-edit/> | |
| 29 | + | |
| 30 | + - 100 commits contributed to the release over the course of 32 calendar days. | |
| 31 | + - 20 commits where understood as [conventional](https://www.conventionalcommits.org). | |
| 32 | + - 3 unique issues were worked on: #1, Uncategorized, #42 | |
| 33 | + | |
| 34 | +##### Commit Details | |
| 35 | + | |
| 36 | +<csr-read-only-do-not-edit/> | |
| 37 | + | |
| 38 | +<details><summary>view details</summary> | |
| 39 | + | |
| 40 | + * **#42** | |
| 41 | + - Just the title (e69de29) | |
| 42 | + - another title (e69de29) | |
| 43 | + * **Uncategorized** | |
| 44 | + - Just the title (e69de29) | |
| 45 | + - title and body (e69de29) | |
| 46 | +</details> | |
| 47 | + | |
| 48 | + | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +--- | |
| 2 | +source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs | |
| 3 | +expression: md | |
| 4 | + | |
| 5 | +--- | |
| 6 | +#### v1.0.2-beta.2 (1970-01-01) | |
| 7 | + | |
| 8 | +<csr-id-0000000000000000000000000000000000000002/> | |
| 9 | + | |
| 10 | +##### New Features (BREAKING) | |
| 11 | + | |
| 12 | +<csr-id-0000000000000000000000000000000000000001/> | |
| 13 | + | |
| 14 | + - verbatim `whatever` the _user_ writes [hello](world) | |
| 15 | + - <csr-id-0000000000000000000000000000000000000003/> this messages comes straight from git conventional and _may_ contain markdown | |
| 16 | + first line | |
| 17 | + second line | |
| 18 | + | |
| 19 | + another paragraph | |
| 20 | + - just another user message, this time | |
| 21 | + with multiple lines | |
| 22 | + | |
| 23 | + and a new paragraph | |
| 24 | + | |
| 25 | + | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +--- | |
| 2 | +source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs | |
| 3 | +expression: md | |
| 4 | + | |
| 5 | +--- | |
| 6 | +#### v1.0.2-beta.2 (1970-01-01) | |
| 7 | + | |
| 8 | +<csr-id-0000000000000000000000000000000000000002/> | |
| 9 | + | |
| 10 | +##### New Features (BREAKING) | |
| 11 | + | |
| 12 | +<csr-id-0000000000000000000000000000000000000001/> | |
| 13 | + | |
| 14 | + - verbatim `whatever` the _user_ writes [hello](world) | |
| 15 | + - <csr-id-0000000000000000000000000000000000000003/> this messages comes straight from git conventional and _may_ contain markdown | |
| 16 | + first line | |
| 17 | + second line | |
| 18 | + | |
| 19 | + another paragraph | |
| 20 | + - just another user message, this time | |
| 21 | + with multiple lines | |
| 22 | + | |
| 23 | + and a new paragraph | |
| 24 | + | |
| 25 | + | |