Skip to content

Commit 944d150

Browse files
committed
build: add format option to changelog generation
--- 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: passed - 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: passed - 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 --- --- type: pre_push_report description: Results of running various checks prior to pushing changes. report: - task: run_javascript_examples status: na - task: run_c_examples status: na - task: run_cpp_examples status: na - task: run_javascript_readme_examples status: failed ---
1 parent c3ef633 commit 944d150

File tree

5 files changed

+70
-4
lines changed

5 files changed

+70
-4
lines changed

.github/workflows/generate_monthly_changelog.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ jobs:
107107
'flags': {
108108
'since': '$UNTIL - 1 week',
109109
'until': '$UNTIL'
110-
}
110+
},
111+
'format': 'aggregated'
111112
});
112113
console.log( changelog.content );
113114
" > ./www-blog-monthly-changelog/monthly_changelog_$UNTIL.md

lib/node_modules/@stdlib/_tools/changelog/generate/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ The function returns an object with the following properties:
4747
The function accepts the following `options`:
4848

4949
- **releaseType**: a release type for which to generate the changelog.
50+
- **format**: whether to generate a `grouped` changelog where commits are grouped by package or `aggregated` one.
5051
- **flags**: `git log` options used to retrieve commits from which to generate the changelog.
5152

5253
By default, the changelog is generated for a non-release. To generate a changelog for an upcoming release, provide a valid release type:
@@ -75,8 +76,26 @@ The following release types are supported:
7576
- `auto`: automatically determine the release type based on parsed commit messages.
7677
- `none`: no release (equivalent to not specifying a release type).
7778

79+
By default, the function generates a `grouped` changelog for namespace packages and an `aggregated` changelog for non-namespace packages. To specify a desired output format, set the `format` option:
80+
81+
```javascript
82+
// Changelog grouped by individual packages:
83+
var changelog = generate( '@stdlib/math/base/utils', {
84+
'format': 'grouped'
85+
});
86+
// returns {...}
87+
88+
// Changelog where all commits, potentially touching many different packages, are merged together:
89+
changelog = generate( '@stdlib/math/base/utils', {
90+
'format': 'aggregated'
91+
});
92+
// returns {...}
93+
```
94+
7895
When generating a changelog, the function uses `git log` to retrieve the commits from which to assemble a set of changes. The `flags` option allows passing options to directly to the `git log` command (e.g., to generate a changelog for a specified time interval or for an individual contributor).
7996

97+
<!-- eslint-disable stdlib/doctest -->
98+
8099
```javascript
81100
var changelog = generate( '@stdlib/ndarray', {
82101
'flags': {

lib/node_modules/@stdlib/_tools/changelog/generate/lib/main.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ function packageSummaryWrapper( pkg, version, name, summary ) {
211211
* @param {string} pkg - package name
212212
* @param {Options} options - function options
213213
* @param {string} [options.releaseType] - release type (`patch`, `minor`, `major`, `prerelease`, `prepatch`, `preminor`, `premajor`, or `auto`)
214+
* @param {string} [options.format] - output format (`grouped` or `aggregated`)
214215
* @param {Options} [options.flags] - `git log` options used to retrieve commits
215216
* @throws {TypeError} must provide a string
216217
* @throws {Error} must provide a valid package name
@@ -245,6 +246,7 @@ function generate( pkg, options ) {
245246
var isNamespacePkg;
246247
var releaseCommits;
247248
var newestRelease;
249+
var outputFormat;
248250
var bySubpackage;
249251
var releaseType;
250252
var nextVersion;
@@ -272,6 +274,10 @@ function generate( pkg, options ) {
272274
throw err;
273275
}
274276
}
277+
outputFormat = opts.format;
278+
if ( !outputFormat ) {
279+
outputFormat = ( isNamespacePkg ) ? 'grouped' : 'aggregated';
280+
}
275281

276282
if ( pkg === '@stdlib' || pkg === '@stdlib/stdlib' ) {
277283
// Case: root package
@@ -341,7 +347,7 @@ function generate( pkg, options ) {
341347
}
342348
}
343349

344-
if ( isNamespacePkg && !opts.flags ) {
350+
if ( outputFormat === 'grouped' ) {
345351
str += releaseSectionStart( nextVersion );
346352
str += '## ' + ( nextVersion || 'Unreleased' ) + ' (' + formatDate() + ')\n\n';
347353
if ( commits.unreleased.length > 0 ) {
@@ -374,7 +380,7 @@ function generate( pkg, options ) {
374380
str += sectionEnd( 'release' );
375381
}
376382
}
377-
if ( isNamespacePkg && !opts.flags ) {
383+
if ( outputFormat === 'grouped' ) {
378384
for ( i = releases.length-1; i >= 0; i-- ) {
379385
version = releases[ i ][ 0 ];
380386
str += releaseSectionStart( version );

lib/node_modules/@stdlib/_tools/changelog/generate/lib/validate.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ var isObject = require( '@stdlib/assert/is-plain-object' );
2424
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
2525
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
2626
var isPlainObject = require( '@stdlib/assert/is-plain-object' );
27+
var indexOf = require( '@stdlib/utils/index-of' );
2728
var format = require( '@stdlib/string/format' );
2829

2930

31+
// VARIABLES //
32+
33+
var FORMAT_OPTIONS = [ 'grouped', 'aggregated' ];
34+
35+
3036
// MAIN //
3137

3238
/**
@@ -36,6 +42,7 @@ var format = require( '@stdlib/string/format' );
3642
* @param {Object} opts - destination for function options
3743
* @param {Options} options - function options
3844
* @param {string} [options.releaseType] - release type
45+
* @param {string} [options.format] - output format (`grouped` or `aggregated`)
3946
* @param {string} [options.flags] - `git log` options used to retrieve commits
4047
* @returns {(Error|null)} error or null
4148
*
@@ -59,6 +66,12 @@ function validate( opts, options ) {
5966
return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'releaseType', opts.releaseType ) );
6067
}
6168
}
69+
if ( hasOwnProp( options, 'format' ) ) {
70+
opts.format = options.format;
71+
if ( indexOf( FORMAT_OPTIONS, opts.format ) === -1 ) {
72+
return new TypeError( format( 'invalid option. `%s` option must be one of the following: "%s". Option: `%s`.', 'format', FORMAT_OPTIONS.join( '", "' ), opts.format ) );
73+
}
74+
}
6275
if ( hasOwnProp( options, 'flags' ) ) {
6376
opts.flags = options.flags;
6477
if ( !isPlainObject( opts.flags ) ) {

lib/node_modules/@stdlib/_tools/changelog/generate/test/test.validate.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,32 @@ tape( 'the function returns an error if provided a `releaseType` option which is
8080
t.end();
8181
});
8282

83+
tape( 'the function returns an error if provided a `format` option which is not a recognized format option', function test( t ) {
84+
var values;
85+
var err;
86+
var i;
87+
88+
values = [
89+
true,
90+
5,
91+
NaN,
92+
null,
93+
void 0,
94+
{},
95+
[],
96+
function noop() {},
97+
'abc'
98+
];
99+
100+
for ( i = 0; i < values.length; i++ ) {
101+
err = validate( {}, {
102+
'format': values[ i ]
103+
});
104+
t.ok( err instanceof TypeError, 'returns a type error when provided ' + values[ i ] );
105+
}
106+
t.end();
107+
});
108+
83109
tape( 'the function returns an error if provided a `flags` option which is not an object', function test( t ) {
84110
var values;
85111
var err;
@@ -111,7 +137,8 @@ tape( 'the function returns `null` if all options are valid', function test( t )
111137
var obj;
112138

113139
opts = {
114-
'releaseType': 'auto'
140+
'releaseType': 'auto',
141+
'format': 'grouped'
115142
};
116143
obj = {};
117144
err = validate( obj, opts );

0 commit comments

Comments
 (0)