4
4
use crate :: git;
5
5
use crate :: util:: run_command;
6
6
use anyhow:: { anyhow, Result } ;
7
- use indoc:: indoc;
8
7
use reqwest:: blocking:: Client ;
9
8
use semver:: Version ;
10
9
use std:: fs:: File ;
@@ -364,65 +363,27 @@ impl Prepare {
364
363
365
364
fn append_vrl_changelog_to_release_cue ( & self ) -> Result < ( ) > {
366
365
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
- }
373
366
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" ) ) ;
375
370
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
+ }
380
374
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 ( ) ?;
407
377
408
- let mut found_changelog = false ;
409
- let changelog_marker = "changelog: [" ;
378
+ let block = format_vrl_changelog_block ( & vrl_changelog) ;
410
379
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) ;
415
381
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) ?;
423
385
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( ) ) ) ;
426
387
debug ! ( "Successfully added VRL changelog to the release cue file." ) ;
427
388
Ok ( ( ) )
428
389
}
@@ -445,6 +406,45 @@ fn get_latest_version_from_vector_tags() -> Result<Version> {
445
406
. map_err ( |e| anyhow:: anyhow!( "Failed to parse version from tag '{latest_tag}': {e}" ) )
446
407
}
447
408
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 = "\t vrl_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
+
448
448
fn get_latest_vrl_tag_and_changelog ( ) -> Result < String > {
449
449
let client = Client :: new ( ) ;
450
450
@@ -497,3 +497,42 @@ fn get_latest_vrl_tag_and_changelog() -> Result<String> {
497
497
498
498
Ok ( section. join ( "\n " ) )
499
499
}
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
+ "\t vrl_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