From 0c29e666b80bebc67502ba5ec458c26066bc685a Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Sun, 16 Mar 2025 15:16:44 -0400 Subject: [PATCH 1/4] build: strip YAML fontmatter from breaking changes in changelog --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../generate/lib/breaking_changes.js | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js index 6f51ef8ab74d..ea6d47eef40d 100644 --- a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js +++ b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js @@ -1,4 +1,3 @@ - /** * @license Apache-2.0 * @@ -33,10 +32,44 @@ var heading = require( './heading.js' ); // VARIABLES // var STDLIB_GITHUB_URL = 'https://github.com/stdlib-js/stdlib/commit'; +var RE_YAML_DELIMITER = /^\s*---\s*$/; // FUNCTIONS // +/** +* Strips YAML frontmatter blocks from text. +* +* @private +* @param {string} text - text to process +* @returns {string} text without YAML blocks +*/ +function stripYamlBlocks( text ) { + var result; + var inYaml; + var lines; + var i; + + lines = text.split( '\n' ); + result = []; + inYaml = false; + + for ( i = 0; i < lines.length; i++ ) { + // Check for YAML delimiter (---) with optional whitespace: + if ( RE_YAML_DELIMITER.test( lines[i] ) ) { + inYaml = !inYaml; // Toggle YAML block state + continue; + } + + // Only include lines that are not part of YAML blocks: + if ( !inYaml ) { + result.push( lines[i] ); + } + } + + return trim( result.join( '\n' ) ); +} + /** * Formats a breaking change. * @@ -54,9 +87,13 @@ var STDLIB_GITHUB_URL = 'https://github.com/stdlib-js/stdlib/commit'; * // returns '- [`abcdef1`](https://github.com/stdlib-js/stdlib/commit/abcdef1234567890): beep' */ function formatBreakingChange( note ) { - var parts = note.text.split( '\n' ); - var hash = trim( note.hash ); - var out = '- [`'+hash.substring( 0, 7 )+'`]('+STDLIB_GITHUB_URL+'/'+hash+'): '+parts[ 0 ]; + var parts; + var hash; + var out; + + parts = stripYamlBlocks( note.text ).split( '\n' ); + hash = trim( note.hash ); + out = '- [`'+hash.substring( 0, 7 )+'`]('+STDLIB_GITHUB_URL+'/'+hash+'): '+parts[ 0 ]; if ( parts.length > 1 ) { out +='\n\n'; out += ' - '; From a28c9354770bbf80dce1e945df4f182f93242005 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Mon, 17 Mar 2025 19:58:33 -0400 Subject: [PATCH 2/4] chore: address PR feedback --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../generate/lib/breaking_changes.js | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js index ea6d47eef40d..5622ab430385 100644 --- a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js +++ b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js @@ -23,6 +23,7 @@ var filter = require( '@stdlib/array/base/filter' ); var trim = require( '@stdlib/string/trim' ); var map = require( '@stdlib/utils/map' ); +var reEOL = require( '@stdlib/regexp/eol' ); var collectField = require( './collect_field.js' ); var sectionStart = require( './section_start.js' ); var sectionEnd = require( './section_end.js' ); @@ -38,19 +39,17 @@ var RE_YAML_DELIMITER = /^\s*---\s*$/; // FUNCTIONS // /** -* Strips YAML frontmatter blocks from text. +* Strips YAML frontmatter blocks from text lines. * * @private -* @param {string} text - text to process -* @returns {string} text without YAML blocks +* @param {Array} lines - text lines to process +* @returns {Array} text lines without YAML blocks */ -function stripYamlBlocks( text ) { +function stripYamlBlocks( lines ) { var result; var inYaml; - var lines; var i; - lines = text.split( '\n' ); result = []; inYaml = false; @@ -67,7 +66,7 @@ function stripYamlBlocks( text ) { } } - return trim( result.join( '\n' ) ); + return result; } /** @@ -87,17 +86,39 @@ function stripYamlBlocks( text ) { * // returns '- [`abcdef1`](https://github.com/stdlib-js/stdlib/commit/abcdef1234567890): beep' */ function formatBreakingChange( note ) { - var parts; + var contentLines; + var trimmedLine; + var firstLine; + var restLines; + var textLines; var hash; var out; + var i; - parts = stripYamlBlocks( note.text ).split( '\n' ); + textLines = note.text.split( reEOL.REGEXP ); + contentLines = stripYamlBlocks( textLines ); + firstLine = ''; + restLines = []; hash = trim( note.hash ); - out = '- [`'+hash.substring( 0, 7 )+'`]('+STDLIB_GITHUB_URL+'/'+hash+'): '+parts[ 0 ]; - if ( parts.length > 1 ) { - out +='\n\n'; - out += ' - '; - out += parts.slice( 1 ).join( '\n ' ); + + for ( i = 0; i < contentLines.length; i++ ) { + trimmedLine = trim( contentLines[i] ); + if ( trimmedLine !== '' ) { + // If this is our first non-empty line, it's the firstLine... + if ( firstLine === '' ) { + firstLine = trimmedLine; + } else { + restLines.push( trimmedLine ); + } + } + } + + // Construct output string - use a single string concatenation when possible + out = '- [`' + hash.substring( 0, 7 ) + '`](' + STDLIB_GITHUB_URL + '/' + hash + '): ' + firstLine; + + if ( restLines.length > 0 ) { + out += '\n\n'; + out += ' - ' + restLines.join( '\n ' ); out += '\n'; } return out; From 04e4fde16b106c83b4e691819b46d71cbfbabe5f Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Sun, 20 Apr 2025 18:06:41 -0400 Subject: [PATCH 3/4] build: refactor to squeeze multiple empty lines into single empty lines --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../generate/lib/breaking_changes.js | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js index 5622ab430385..530b45a41b63 100644 --- a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js +++ b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js @@ -39,34 +39,48 @@ var RE_YAML_DELIMITER = /^\s*---\s*$/; // FUNCTIONS // /** -* Strips YAML frontmatter blocks from text lines. +* Processes commit message text by removing YAML blocks and squashing multiple empty lines into a single empty line. * * @private * @param {Array} lines - text lines to process -* @returns {Array} text lines without YAML blocks +* @returns {Array} text lines without YAML blocks and multiple empty lines */ function stripYamlBlocks( lines ) { - var result; + var previousLineEmpty; + var trimmed; var inYaml; + var out; var i; - result = []; + previousLineEmpty = false; + out = []; inYaml = false; for ( i = 0; i < lines.length; i++ ) { // Check for YAML delimiter (---) with optional whitespace: - if ( RE_YAML_DELIMITER.test( lines[i] ) ) { + if ( RE_YAML_DELIMITER.test( lines[ i ] ) ) { inYaml = !inYaml; // Toggle YAML block state continue; } // Only include lines that are not part of YAML blocks: if ( !inYaml ) { - result.push( lines[i] ); + trimmed = trim( lines[ i ] ); + + if ( trimmed === '' ) { + // Only add an empty line if the previous line wasn't empty: + if ( !previousLineEmpty && out.length > 0 ) { + previousLineEmpty = true; + out.push( '' ); + } + } else { + previousLineEmpty = false; + out.push( lines[ i ] ); // Preserve original line formatting + } } } - return result; + return out; } /** @@ -87,31 +101,19 @@ function stripYamlBlocks( lines ) { */ function formatBreakingChange( note ) { var contentLines; - var trimmedLine; + var textLines; var firstLine; var restLines; - var textLines; var hash; var out; - var i; textLines = note.text.split( reEOL.REGEXP ); contentLines = stripYamlBlocks( textLines ); - firstLine = ''; - restLines = []; - hash = trim( note.hash ); - for ( i = 0; i < contentLines.length; i++ ) { - trimmedLine = trim( contentLines[i] ); - if ( trimmedLine !== '' ) { - // If this is our first non-empty line, it's the firstLine... - if ( firstLine === '' ) { - firstLine = trimmedLine; - } else { - restLines.push( trimmedLine ); - } - } - } + // If we have content, first element is the first line: + firstLine = contentLines[ 0 ] || ''; + restLines = contentLines.slice( 1 ); + hash = trim( note.hash ); // Construct output string - use a single string concatenation when possible out = '- [`' + hash.substring( 0, 7 ) + '`](' + STDLIB_GITHUB_URL + '/' + hash + '): ' + firstLine; From 2dfc50f17afb2d5ff7ce006ab606e576044e9cd3 Mon Sep 17 00:00:00 2001 From: Athan Date: Sun, 20 Apr 2025 19:15:35 -0700 Subject: [PATCH 4/4] chore: clean-up Signed-off-by: Athan --- .../generate/lib/breaking_changes.js | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js index 530b45a41b63..9ea392ab0b4d 100644 --- a/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js +++ b/lib/node_modules/@stdlib/_tools/changelog/generate/lib/breaking_changes.js @@ -43,43 +43,38 @@ var RE_YAML_DELIMITER = /^\s*---\s*$/; * * @private * @param {Array} lines - text lines to process -* @returns {Array} text lines without YAML blocks and multiple empty lines +* @returns {Array} processed commit message lines */ function stripYamlBlocks( lines ) { var previousLineEmpty; - var trimmed; var inYaml; var out; var i; previousLineEmpty = false; - out = []; inYaml = false; - + out = []; for ( i = 0; i < lines.length; i++ ) { // Check for YAML delimiter (---) with optional whitespace: if ( RE_YAML_DELIMITER.test( lines[ i ] ) ) { inYaml = !inYaml; // Toggle YAML block state continue; } - // Only include lines that are not part of YAML blocks: - if ( !inYaml ) { - trimmed = trim( lines[ i ] ); - - if ( trimmed === '' ) { - // Only add an empty line if the previous line wasn't empty: - if ( !previousLineEmpty && out.length > 0 ) { - previousLineEmpty = true; - out.push( '' ); - } - } else { - previousLineEmpty = false; - out.push( lines[ i ] ); // Preserve original line formatting + if ( inYaml ) { + continue; + } + if ( trim( lines[ i ] ) === '' ) { + // Only add an empty line if the previous line wasn't empty: + if ( !previousLineEmpty && out.length > 0 ) { + previousLineEmpty = true; + out.push( '' ); } + } else { + previousLineEmpty = false; + out.push( lines[ i ] ); // Preserve original line formatting } } - return out; } @@ -115,9 +110,8 @@ function formatBreakingChange( note ) { restLines = contentLines.slice( 1 ); hash = trim( note.hash ); - // Construct output string - use a single string concatenation when possible + // Construct output string: out = '- [`' + hash.substring( 0, 7 ) + '`](' + STDLIB_GITHUB_URL + '/' + hash + '): ' + firstLine; - if ( restLines.length > 0 ) { out += '\n\n'; out += ' - ' + restLines.join( '\n ' ); @@ -148,18 +142,18 @@ function isBreakingChange( note ) { * @returns {string} list of breaking changes */ function breakingChanges( commits ) { - var breakingChanges; + var changes; var notes; var out; notes = collectField( commits, 'notes' ); - breakingChanges = filter( notes, isBreakingChange ); - if ( breakingChanges.length === 0 ) { + changes = filter( notes, isBreakingChange ); + if ( changes.length === 0 ) { return ''; } out = sectionStart( 'breaking-changes' ); out += heading( 'BREAKING CHANGES', 3 ); - out += map( breakingChanges, formatBreakingChange ).join( '\n' ); + out += map( changes, formatBreakingChange ).join( '\n' ); out += sectionEnd( 'breaking-changes' ); return out; }