-
-
Notifications
You must be signed in to change notification settings - Fork 159
Add --tag-parser-pattern & --tag-parser-replacement for unconventional tag coercion into valid semver. #222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 6 commits
c8b0c0c
62f2a2b
f2a7196
2a6e67d
8061aeb
d0c8cd6
cfbb309
7a9332d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,39 +21,41 @@ Usage: auto-changelog [options] | |
|
||
Options: | ||
|
||
-o, --output [file] # output file, default: CHANGELOG.md | ||
-c, --config [file] # config file location, default: .auto-changelog | ||
-t, --template [template] # specify template to use [compact, keepachangelog, json], default: compact | ||
-r, --remote [remote] # specify git remote to use for links, default: origin | ||
-p, --package # use version from package.json as latest release | ||
-v, --latest-version [version] # use specified version as latest release | ||
-u, --unreleased # include section for unreleased changes | ||
-l, --commit-limit [count] # number of commits to display per release, default: 3 | ||
-b, --backfill-limit [count] # number of commits to backfill empty releases with, default: 3 | ||
--commit-url [url] # override url for commits, use {id} for commit id | ||
--issue-url [url] # override url for issues, use {id} for issue id | ||
--merge-url [url] # override url for merges, use {id} for merge id | ||
--compare-url [url] # override url for compares, use {from} and {to} for tags | ||
--issue-pattern [regex] # override regex pattern for issues in commit messages | ||
--breaking-pattern [regex] # regex pattern for breaking change commits | ||
--merge-pattern [regex] # add custom regex pattern for merge commits | ||
--ignore-commit-pattern [regex] # pattern to ignore when parsing commits | ||
--tag-pattern [regex] # override regex pattern for version tags | ||
--tag-prefix [prefix] # prefix used in version tags, default: v | ||
--starting-version [tag] # specify earliest version to include in changelog | ||
--starting-date [yyyy-mm-dd] # specify earliest date to include in changelog | ||
--sort-commits [property] # sort commits by property [relevance, date, date-desc, subject, subject-desc], default: relevance | ||
--release-summary # display tagged commit message body as release summary | ||
--unreleased-only # only output unreleased changes | ||
--hide-empty-releases # hide empty releases | ||
--hide-credit # hide auto-changelog credit | ||
--handlebars-setup [file] # handlebars setup file | ||
--append-git-log [string] # string to append to git log command | ||
--append-git-tag [string] # string to append to git tag command | ||
--prepend # prepend changelog to output file | ||
--stdout # output changelog to stdout | ||
-V, --version # output the version number | ||
-h, --help # output usage information | ||
-o, --output [file] # output file, default: CHANGELOG.md | ||
-c, --config [file] # config file location, default: .auto-changelog | ||
-t, --template [template] # specify template to use [compact, keepachangelog, json], default: compact | ||
-r, --remote [remote] # specify git remote to use for links, default: origin | ||
-p, --package # use version from package.json as latest release | ||
-v, --latest-version [version] # use specified version as latest release | ||
-u, --unreleased # include section for unreleased changes | ||
-l, --commit-limit [count] # number of commits to display per release, default: 3 | ||
-b, --backfill-limit [count] # number of commits to backfill empty releases with, default: 3 | ||
--commit-url [url] # override url for commits, use {id} for commit id | ||
--issue-url [url] # override url for issues, use {id} for issue id | ||
--merge-url [url] # override url for merges, use {id} for merge id | ||
--compare-url [url] # override url for compares, use {from} and {to} for tags | ||
--issue-pattern [regex] # override regex pattern for issues in commit messages | ||
--breaking-pattern [regex] # regex pattern for breaking change commits | ||
--merge-pattern [regex] # add custom regex pattern for merge commits | ||
--ignore-commit-pattern [regex] # pattern to ignore when parsing commits | ||
--tag-pattern [regex] # override regex pattern for version tags | ||
--tag-prefix [prefix] # prefix used in version tags, default: v | ||
--tag-parser-pattern [regex] # pattern used to capture values in tags for replacement | ||
--tag-parser-replacement [string] # replaces captures supplied in the --tag-parser-pattern option to create valid semver tags | ||
--starting-version [tag] # specify earliest version to include in changelog | ||
--starting-date [yyyy-mm-dd] # specify earliest date to include in changelog | ||
--sort-commits [property] # sort commits by property [relevance, date, date-desc, subject, subject-desc], default: relevance | ||
--release-summary # display tagged commit message body as release summary | ||
--unreleased-only # only output unreleased changes | ||
--hide-empty-releases # hide empty releases | ||
--hide-credit # hide auto-changelog credit | ||
--handlebars-setup [file] # handlebars setup file | ||
--append-git-log [string] # string to append to git log command | ||
--append-git-tag [string] # string to append to git tag command | ||
--prepend # prepend changelog to output file | ||
--stdout # output changelog to stdout | ||
-V, --version # output the version number | ||
-h, --help # output usage information | ||
|
||
|
||
# Write log to CHANGELOG.md in current directory | ||
|
@@ -158,15 +160,6 @@ You can also store config options in an `.auto-changelog` file in your project r | |
|
||
Note that any options set in `package.json` will take precedence over any set in `.auto-changelog`. | ||
|
||
#### Tag prefixes | ||
|
||
Use `--tag-prefix [prefix]` if you prefix your version tags with a certain string: | ||
|
||
```bash | ||
# When all versions are tagged like my-package/1.2.3 | ||
auto-changelog --tag-prefix my-package/ | ||
``` | ||
|
||
#### Tag patterns | ||
|
||
By default, `auto-changelog` looks for valid semver tags to build a list of releases. If you are using another format (or want to include all tags), use `--tag-pattern [regex]`: | ||
|
@@ -179,6 +172,28 @@ auto-changelog --tag-pattern build-\d+ | |
auto-changelog --tag-pattern .+ | ||
``` | ||
|
||
Including tags using this method does not gurantee correct tag order however since the sorting compares semver versions rather than their date or alphabetical order. For proper custom tag order, please refer to the [Tag parsing](#tag-parsing) section. Note, if a tag can be properly coerced into a valid semver string via the parsing options, the `--tag-pattern` is no longer needed. | ||
|
||
#### Tag parsing | ||
|
||
There are 2 mechanisms that help auto-changelog properly parse your tags. | ||
|
||
Use `--tag-prefix [prefix]` if you prefix your version tags with a certain string: | ||
|
||
```bash | ||
# When all versions are tagged like "my-package/1.2.3" | ||
auto-changelog --tag-prefix my-package/ | ||
``` | ||
|
||
Alternatively, if you have an unconventional tagging pattern, you can provide a capture pattern and a replacement string through the `--tag-parser-pattern [regex]` and `--tag-parser-replacement [string]` options. | ||
|
||
```bash | ||
# When all versions are tagged like "[email protected] build123" | ||
auto-changelog --tag-parser-pattern "^my-package@(\d+)\.(\d+) build(\d+)$" --tag-parser-replacement "\$1.\$2.0-build.\$3" | ||
``` | ||
|
||
Note, both options need to be supplied for this to work. Also note, `$` signs in the replacement string must be escaped. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documents parsing strategies and their differences. |
||
#### Breaking changes | ||
|
||
If you use a common pattern in your commit messages for breaking changes, use `--breaking-pattern` to highlight those commits as breaking changes in your changelog. Breaking change commits will always be listed as part of a release, regardless of any `--commit-limit` set. | ||
|
@@ -283,7 +298,7 @@ Use `{{#commit-list}}` to render a list of commits depending on certain patterns | |
| `heading` | A heading for the list, only renders if at least one commit matches | | ||
| `message` | A regex pattern to match against the entire commit message | | ||
| `subject` | A regex pattern to match against the commit subject only | | ||
| `exclude` | A regex pattern to exclude from the list – useful for avoiding listing commits more than once | | ||
| `exclude` | A regex pattern to exclude from the list – useful for avoiding listing commits more than once | | ||
|
||
#### Replacing text | ||
|
||
|
@@ -332,4 +347,4 @@ The command parses your git commit history and generates a changelog based on ta | |
|
||
#### Why do I need it? | ||
|
||
Because keeping a changelog can be tedious and difficult to get right. If you don’t have the patience for a hand-crafted, bespoke changelog then this makes keeping one rather easy. It also can be [automated if you’re feeling extra lazy](#what-you-might-do-if-youre-clever). | ||
Because keeping a changelog can be tedious and difficult to get right. If you don’t have the patience for a hand-crafted, bespoke changelog then this makes keeping one rather easy. It also can be [automated if you’re feeling extra lazy](#what-you-might-do-if-youre-clever). |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,8 @@ const getOptions = async argv => { | |
.option('--ignore-commit-pattern <regex>', 'pattern to ignore when parsing commits') | ||
.option('--tag-pattern <regex>', 'override regex pattern for version tags') | ||
.option('--tag-prefix <prefix>', 'prefix used in version tags') | ||
.option('--tag-parser-pattern <regex>', 'pattern used to capture values in tags for replacement') | ||
.option('--tag-parser-replacement <string>', 'replaces captures supplied in the --tag-parser-pattern option to create valid semver tags') | ||
Comment on lines
+47
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adds options to commander. |
||
.option('--starting-version <tag>', 'specify earliest version to include in changelog') | ||
.option('--starting-date <yyyy-mm-dd>', 'specify earliest date to include in changelog') | ||
.option('--sort-commits <property>', `sort commits by property [relevance, date, date-desc], default: ${DEFAULT_OPTIONS.sortCommits}`) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,17 +47,17 @@ const getLimit = (tags, { unreleasedOnly, startingVersion, startingDate }) => { | |
return tags.length | ||
} | ||
|
||
const parseTag = ({ tagPrefix }) => string => { | ||
const parseTag = (options) => string => { | ||
const [tag, date] = string.split(DIVIDER) | ||
return { | ||
tag, | ||
date, | ||
title: tag, | ||
version: inferSemver(tag.replace(tagPrefix, '')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moves the tagPrefix replacement logic into the |
||
version: inferSemver(tag, options) | ||
} | ||
} | ||
|
||
const enrichTag = ({ getCompareLink, tagPattern }) => (t, index, tags) => { | ||
const enrichTag = ({ getCompareLink }) => (t, index, tags) => { | ||
const previous = tags[index + 1] | ||
return { | ||
isoDate: t.date.slice(0, 10), | ||
|
@@ -94,15 +94,25 @@ const sortTags = ({ version: a }, { version: b }) => { | |
return a < b ? 1 : -1 | ||
} | ||
|
||
const inferSemver = tag => { | ||
const inferSemver = (tag, { tagPrefix, tagParserPattern, tagParserReplacement }) => { | ||
if (!!tagParserPattern && !!tagParserReplacement) { | ||
return tag.replace(new RegExp(tagParserPattern), tagParserReplacement) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adds the logic for the pattern/replacement options. |
||
|
||
if (!!tagPrefix && tag.startsWith(tagPrefix)) { | ||
tag = tag.replace(new RegExp(`^${tagPrefix}`), '') | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are removing the "prefix" via the |
||
|
||
if (/^v?\d+$/.test(tag)) { | ||
// v1 becomes v1.0.0 | ||
return `${tag}.0.0` | ||
} | ||
|
||
if (/^v?\d+\.\d+$/.test(tag)) { | ||
// v1.0 becomes v1.0.0 | ||
return `${tag}.0` | ||
} | ||
|
||
return tag | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,4 +166,19 @@ describe('fetchTags', () => { | |
'v0.1.0' | ||
]) | ||
}) | ||
|
||
it('supports tag parsing through --tag-parser-pattern and --tag-parser-replacement', async () => { | ||
mock('cmd', () => Promise.resolve([ | ||
'version 0.1.0 || build 2345---2000-02-01', | ||
'version 2.1.0 || build 2355---2000-02-01', | ||
'version 3.2.1 || build 2367---2000-02-01' | ||
].join('\n'))) | ||
|
||
const tags = await fetchTags({ ...options, tagParserPattern: '^version (\\d+)\\.(\\d+)\\.(\\d+) \\|\\| build (\\d+)$', tagParserReplacement: '$1.$2.$3-build.$4' }) | ||
expect(tags.map(t => t.version)).to.deep.equal([ | ||
'3.2.1-build.2367', | ||
'2.1.0-build.2355', | ||
'0.1.0-build.2345' | ||
]) | ||
}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adds test. |
||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documents option usage.