History

Foundation for rendering links if needed (#198)

Sebastian Thiel committed 5 years ago

Commit ba4ce961 parent e766b018 files · +156 −19Browse files

Unified · Split

8 files
  1. cargo-smart-release/src/changelog/mod.rs +1 −1
  2. cargo-smart-release/src/changelog/write.rs +22 −5
  3. cargo-smart-release/src/command/changelog.rs +11 −1
  4. cargo-smart-release/src/command/release/manifest.rs +1 −1
  5. cargo-smart-release/tests/changelog/write_and_parse/mod.rs +23 −11
  6. cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__all_section_types_round_trips_lossy-2.snap +48 −0
  7. cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__conventional_write_empty_messages-3.snap +25 −0
  8. cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__conventional_write_empty_messages-4.snap +25 −0
cargo-smart-release/src/changelog/mod.rs+1−1
@@ -6,7 +6,7 @@ mod init; · 5 unmodified lines
6mod merge;6mod merge;
7mod parse;7mod parse;
8pub mod section;8pub mod section;
9mod write;9pub mod write;
10 10
11#[derive(PartialEq, Eq, Debug, Clone)]11#[derive(PartialEq, Eq, Debug, Clone)]
12pub enum Section {12pub enum Section {
cargo-smart-release/src/changelog/write.rs+22−5
@@ -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)]
24pub 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
22impl Section {34impl Section {
23 pub const UNKNOWN_TAG_START: &'static str = "<csr-unknown>";35 pub const UNKNOWN_TAG_START: &'static str = "<csr-unknown>";
24 pub const UNKNOWN_TAG_END: &'static str = "<csr-unknown/>";36 pub const UNKNOWN_TAG_END: &'static str = "<csr-unknown/>";
25 pub const READONLY_TAG: &'static str = "<csr-read-only-do-not-edit/>\n"; // needs a newline to not interfere with formatting37 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 match self {40 match self {
29 Section::Verbatim { text, .. } => out.write_all(text.as_bytes()),41 Section::Verbatim { text, .. } => out.write_all(text.as_bytes()),
30 Section::Release {42 Section::Release {
@@ -55,7 +67,7 @@ impl Section { · 24 unmodified lines
55 67
56 let section_level = *heading_level + 1;68 let section_level = *heading_level + 1;
57 for segment in segments {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 if !unknown.is_empty() {72 if !unknown.is_empty() {
61 writeln!(out, "{}", Section::UNKNOWN_TAG_START)?;73 writeln!(out, "{}", Section::UNKNOWN_TAG_START)?;
@@ -73,16 +85,21 @@ fn heading(level: usize) -> String { · 11 unmodified lines
73}85}
74 86
75impl ChangeLog {87impl 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 for section in &self.sections {89 for section in &self.sections {
78 section.write_to(&mut out)?;90 section.write_to(&mut out, link_mode)?;
79 }91 }
80 Ok(())92 Ok(())
81 }93 }
82}94}
83 95
84impl section::Segment {96impl 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 match self {103 match self {
87 Segment::User { markdown } => out.write_all(markdown.as_bytes())?,104 Segment::User { markdown } => out.write_all(markdown.as_bytes())?,
88 Segment::Conventional(segment::Conventional {105 Segment::Conventional(segment::Conventional {
cargo-smart-release/src/command/changelog.rs+11−1
@@ -1,3 +1,4 @@
1use crate::changelog::write::Linkables;
1use crate::{bat, command::changelog::Options, git, utils::will, ChangeLog};2use crate::{bat, command::changelog::Options, git, utils::will, ChangeLog};
2 3
3pub fn changelog(opts: Options, crates: Vec<String>) -> anyhow::Result<()> {4pub 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 .expect("contained in workspace")34 .expect("contained in workspace")
34 .display()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 if let Some(bat) = bat.as_ref() {47 if let Some(bat) = bat.as_ref() {
38 bat.display_to_tty(lock.lock_path())?;48 bat.display_to_tty(lock.lock_path())?;
39 }49 }
cargo-smart-release/src/command/release/manifest.rs+1−1
@@ -86,7 +86,7 @@ pub(in crate::command::release_impl) fn edit_version_and_fixup_dependent_crates_ · 85 unmodified lines
86 if !recent_release_in_log.is_essential() {86 if !recent_release_in_log.is_essential() {
87 empty_changelogs_for_current_version.push(pending_changelog_changes.len());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 pending_changelog_changes.push((publishee, changed_relevant_content, lock));90 pending_changelog_changes.push((publishee, changed_relevant_content, lock));
91 }91 }
92 }92 }
cargo-smart-release/tests/changelog/write_and_parse/mod.rs+23−11
@@ -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 {48 for link_mode in &[
49 let mut buf = Vec::<u8>::new();49 changelog::write::Linkables::AsText,
50 log.write_to(&mut buf)?;50 changelog::write::Linkables::AsLinks {
51 let md = buf.to_str()?;51 repository_url: "https://github.com/user/repo".into(),
52 insta::assert_snapshot!(md);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);60 let parsed_log = ChangeLog::from_markdown(md);
55 assert_eq!(parsed_log, log, "we can parse this back losslessly");61 assert_eq!(parsed_log, log, "we can parse this back losslessly");
62 }
56 }63 }
57 Ok(())64 Ok(())
58}65}
59 66
60#[test]67#[test]
61fn all_section_types_round_trips_lossy() -> Result {68fn all_section_types_round_trips_lossy() -> Result {
62 let mut log = ChangeLog {69 let log = ChangeLog {
63 sections: vec![70 sections: vec![
64 Section::Verbatim {71 Section::Verbatim {
65 text: "# Changelog\n\nmy very own header\n\n".into(),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 // NOTE: we can't run this a second time as the statistical information will be gone (it was never parsed back)147 // NOTE: we can't run this a second time as the statistical information will be gone (it was never parsed back)
135 let mut buf = Vec::<u8>::new();148 let mut buf = Vec::<u8>::new();
136 log.write_to(&mut buf)?;149 log.write_to(&mut buf, link_mode)?;
137 let md = buf.to_str()?;150 let md = buf.to_str()?;
138 insta::assert_snapshot!(md);151 insta::assert_snapshot!(md);
139 152
140 let parsed_log = ChangeLog::from_markdown(md);153 let parsed_log = ChangeLog::from_markdown(md);
141 assert_eq!(parsed_log, log, "we must be able to parse the exact input back");154 assert_eq!(parsed_log, log, "we must be able to parse the exact input back");
142 log = parsed_log;
143 }155 }
144 Ok(())156 Ok(())
145}157}
cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__all_section_types_round_trips_lossy-2.snap+48−0
@@ -0,0 +1,48 @@
1---
2source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs
3expression: md
4
5---
6# Changelog
7
8my very own header
9
10## Unreleased
11
12<csr-unknown>
13hello
14world
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
cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__conventional_write_empty_messages-3.snap+25−0
@@ -0,0 +1,25 @@
1---
2source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs
3expression: 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
cargo-smart-release/tests/changelog/write_and_parse/snapshots/integration__changelog__write_and_parse__conventional_write_empty_messages-4.snap+25−0
@@ -0,0 +1,25 @@
1---
2source: cargo-smart-release/tests/changelog/write_and_parse/mod.rs
3expression: 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