Skip to content

Commit 9a34b90

Browse files
committed
chore(releasing): update VRL changelog block insertion
1 parent e76f18e commit 9a34b90

File tree

1 file changed

+92
-53
lines changed

1 file changed

+92
-53
lines changed

vdev/src/commands/release/prepare.rs

Lines changed: 92 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use crate::git;
55
use crate::util::run_command;
66
use anyhow::{anyhow, Result};
7-
use indoc::indoc;
87
use reqwest::blocking::Client;
98
use semver::Version;
109
use std::fs::File;
@@ -364,65 +363,27 @@ impl Prepare {
364363

365364
fn append_vrl_changelog_to_release_cue(&self) -> Result<()> {
366365
debug!("append_vrl_changelog_to_release_cue");
367-
let releases_path = &self.repo_root.join("website").join("cue").join("reference").join("releases");
368-
let vector_version = &self.new_vector_version;
369-
let release_cue_path = releases_path.join(format!("{vector_version}.cue"));
370-
if !release_cue_path.is_file() {
371-
return Err(anyhow!("{release_cue_path:?} not found"));
372-
}
373366

374-
let vrl_changelog = get_latest_vrl_tag_and_changelog()?;
367+
let releases_path = self.repo_root.join("website/cue/reference/releases");
368+
let version = &self.new_vector_version;
369+
let cue_path = releases_path.join(format!("{version}.cue"));
375370

376-
let temp_file_path = releases_path.join(format!("{vector_version}.cue.tmp"));
377-
let input_file = File::open(&release_cue_path)?;
378-
let reader = BufReader::new(input_file);
379-
let mut output_file = File::create(&temp_file_path)?;
371+
if !cue_path.is_file() {
372+
return Err(anyhow!("{cue_path:?} not found"));
373+
}
380374

381-
let indent = "\t".repeat(5);
382-
let processed_changelog: String = vrl_changelog
383-
.lines()
384-
.map(|line| {
385-
let line = line.trim();
386-
if line.starts_with('#') {
387-
format!("{indent}#{line}")
388-
} else {
389-
format!("{indent}{line}")
390-
}
391-
})
392-
.collect::<Vec<String>>()
393-
.join("\n");
394-
395-
// Format the new changelog entry
396-
let vrl_cue_block = format!(
397-
indoc! {r#"
398-
{{
399-
type: "feat"
400-
description: """
401-
{}
402-
"""
403-
}},
404-
"#},
405-
processed_changelog
406-
);
375+
let original = fs::read_to_string(&cue_path)?;
376+
let vrl_changelog = get_latest_vrl_tag_and_changelog()?;
407377

408-
let mut found_changelog = false;
409-
let changelog_marker = "changelog: [";
378+
let block = format_vrl_changelog_block(&vrl_changelog);
410379

411-
// Read and write line by line
412-
for line in reader.lines() {
413-
let line = line?;
414-
writeln!(output_file, "{line}")?;
380+
let updated = insert_block_after_changelog(&original, &block);
415381

416-
// Check if this is the changelog line
417-
if !found_changelog && line.trim().starts_with(changelog_marker) {
418-
// Insert the new entry after the changelog opening
419-
writeln!(output_file, "{vrl_cue_block}")?;
420-
found_changelog = true;
421-
}
422-
}
382+
let tmp_path = cue_path.with_extension("cue.tmp");
383+
fs::write(&tmp_path, &updated)?;
384+
fs::rename(&tmp_path, &cue_path)?;
423385

424-
fs::rename(&temp_file_path, &release_cue_path)?;
425-
run_command(&format!("cue fmt {release_cue_path:?}"));
386+
run_command(&format!("cue fmt {}", cue_path.display()));
426387
debug!("Successfully added VRL changelog to the release cue file.");
427388
Ok(())
428389
}
@@ -445,6 +406,45 @@ fn get_latest_version_from_vector_tags() -> Result<Version> {
445406
.map_err(|e| anyhow::anyhow!("Failed to parse version from tag '{latest_tag}': {e}"))
446407
}
447408

409+
fn format_vrl_changelog_block(changelog: &str) -> String {
410+
let double_tab = "\t\t";
411+
let body = changelog
412+
.lines()
413+
.map(|line| {
414+
let line = line.trim();
415+
if line.starts_with('#') {
416+
format!("{double_tab}#{line}")
417+
} else {
418+
format!("{double_tab}{line}")
419+
}
420+
})
421+
.collect::<Vec<_>>()
422+
.join("\n");
423+
424+
let opening = "\tvrl_changelog: \"\"\"";
425+
let closing = format!("{double_tab}\"\"\"");
426+
427+
format!("{opening}\n{body}\n{closing}")
428+
}
429+
430+
fn insert_block_after_changelog(original: &str, block: &str) -> String {
431+
let mut result = Vec::new();
432+
let mut inserted = false;
433+
434+
for line in original.lines() {
435+
result.push(line.to_string());
436+
437+
// Insert *after* the line containing only the closing `]` (end of changelog array)
438+
if !inserted && line.trim() == "]" {
439+
result.push(String::new()); // empty line before
440+
result.push(block.to_string());
441+
inserted = true;
442+
}
443+
}
444+
445+
result.join("\n")
446+
}
447+
448448
fn get_latest_vrl_tag_and_changelog() -> Result<String> {
449449
let client = Client::new();
450450

@@ -497,3 +497,42 @@ fn get_latest_vrl_tag_and_changelog() -> Result<String> {
497497

498498
Ok(section.join("\n"))
499499
}
500+
501+
#[cfg(test)]
502+
mod tests {
503+
use crate::commands::release::prepare::{format_vrl_changelog_block, insert_block_after_changelog};
504+
use indoc::indoc;
505+
506+
#[test]
507+
fn test_insert_block_after_changelog() {
508+
let vrl_changelog = "### [0.2.0]\n- Feature\n- Fix";
509+
let vrl_changelog_block = format_vrl_changelog_block(vrl_changelog);
510+
511+
let expected = concat!(
512+
"\tvrl_changelog: \"\"\"\n",
513+
"\t\t#### [0.2.0]\n",
514+
"\t\t- Feature\n",
515+
"\t\t- Fix\n",
516+
"\t\t\"\"\""
517+
);
518+
519+
assert_eq!(vrl_changelog_block, expected);
520+
521+
let original = indoc! {r#"
522+
version: "1.2.3"
523+
changelog: [
524+
{
525+
type: "fix"
526+
description: "Some fix"
527+
},
528+
]
529+
"#};
530+
let updated = insert_block_after_changelog(original, &vrl_changelog_block);
531+
532+
// Assert the last 5 lines match the VRL changelog block
533+
let expected_lines_len = 5;
534+
let updated_tail: Vec<&str> = updated.lines().rev().take(expected_lines_len).collect::<Vec<_>>().into_iter().rev().collect();
535+
let expected_lines: Vec<&str> = vrl_changelog_block.lines().collect();
536+
assert_eq!(updated_tail, expected_lines);
537+
}
538+
}

0 commit comments

Comments
 (0)