Skip to content

Commit 4fcd4a7

Browse files
authored
feat!: adds configurable conventionalcommits preset (#323)
BREAKING CHANGE: we now use the conventionalcommits preset by default, which directly tracks conventionalcommits.org.
1 parent 71e8a04 commit 4fcd4a7

File tree

8 files changed

+113
-14
lines changed

8 files changed

+113
-14
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,39 @@ Now you can use `standard-version` in place of `npm version`.
6565

6666
This has the benefit of allowing you to use `standard-version` on any repo/package without adding a dev dependency to each one.
6767

68+
## Configuration
69+
70+
You can configure `standard-version` either by:
71+
72+
1. Placing a `standard-version` stanza in your `package.json` (assuming
73+
your project is JavaScript).
74+
1. Creating a `.versionrc` or `.versionrc.json`.
75+
76+
Any of the command line paramters accepted by `standard-version` can instead
77+
be provided via configuration.
78+
79+
### Customizing CHANGELOG Generation
80+
81+
By default, `standard-version` uses the [conventionalcommits preset](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits).
82+
83+
This preset:
84+
85+
* adheres closely to the [conventionalcommits.org](https://www.conventionalcommits.org)
86+
specification.
87+
* is highly configurable, following the configuration specification
88+
[maintained here](https://github.com/conventional-changelog/conventional-changelog-config-spec).
89+
* _we've documented these config settings as a recommendation to other tooling makers._
90+
91+
There are a variety of dials and knobs you can turn related to CHANGELOG generation.
92+
93+
As an example, suppose you're using GitLab, rather than GitHub, you might modify the following variables:
94+
95+
* `commitUrlFormat`: the URL format of commit SHAs detected in commit messages.
96+
* `compareUrlFormat`: the URL format used to compare two tags.
97+
* `issueUrlFormat`: the URL format used to link to issues.
98+
99+
Making these URLs match GitLab's format, rather than GitHub's.
100+
68101
## CLI Usage
69102

70103
### First Release

command.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
let defaults = require('./defaults')
1+
const findUp = require('find-up')
2+
const defaults = require('./defaults')
3+
const { readFileSync } = require('fs')
24

3-
module.exports = require('yargs')
5+
const configPath = findUp.sync(['.versionrc', '.version.json'])
6+
const config = configPath ? JSON.parse(readFileSync(configPath)) : {}
7+
const spec = require('conventional-changelog-config-spec')
8+
9+
const yargs = require('yargs')
410
.usage('Usage: $0 [options]')
511
.option('release-as', {
612
alias: 'r',
@@ -95,11 +101,25 @@ module.exports = require('yargs')
95101
return true
96102
}
97103
})
98-
.version()
99104
.alias('version', 'v')
100-
.help()
101105
.alias('help', 'h')
102106
.example('$0', 'Update changelog and tag release')
103107
.example('$0 -m "%s: see changelog for details"', 'Update changelog and tag release with custom commit message')
104108
.pkgConf('standard-version')
109+
.config(config)
105110
.wrap(97)
111+
112+
Object.keys(spec.properties).forEach(propertyKey => {
113+
const property = spec.properties[propertyKey]
114+
yargs.option(propertyKey, {
115+
type: property.type,
116+
describe: property.description,
117+
default: property.default,
118+
group: 'Preset Configuration:'
119+
})
120+
})
121+
122+
module.exports = yargs
123+
124+
// TODO: yargs should be populated with keys/descriptions from
125+
// https://github.com/conventional-changelog/conventional-changelog-config-spec

defaults.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
"skip": {},
1212
"dryRun": false,
1313
"gitTagFallback": true,
14-
"preset": "angular"
15-
}
14+
"preset": "conventionalcommits"
15+
}

lib/lifecycles/bump.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const figures = require('figures')
99
const fs = require('fs')
1010
const DotGitignore = require('dotgitignore')
1111
const path = require('path')
12+
const presetLoader = require('../preset-loader')
1213
const runLifecycleScript = require('../run-lifecycle-script')
1314
const semver = require('semver')
1415
const stringifyPackage = require('stringify-package')
@@ -137,7 +138,7 @@ function bumpVersion (releaseAs, args) {
137138
} else {
138139
conventionalRecommendedBump({
139140
debug: args.verbose && console.info.bind(console, 'conventional-recommended-bump'),
140-
preset: args.preset || 'angular',
141+
preset: presetLoader(args),
141142
path: args.path
142143
}, function (err, release) {
143144
if (err) return reject(err)

lib/lifecycles/changelog.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const chalk = require('chalk')
33
const checkpoint = require('../checkpoint')
44
const conventionalChangelog = require('conventional-changelog')
55
const fs = require('fs')
6+
const presetLoader = require('../preset-loader')
67
const runLifecycleScript = require('../run-lifecycle-script')
78
const writeFile = require('../write-file')
89

@@ -32,7 +33,7 @@ function outputChangelog (args, newVersion) {
3233
if (args.dryRun) context = { version: newVersion }
3334
let changelogStream = conventionalChangelog({
3435
debug: args.verbose && console.info.bind(console, 'conventional-changelog'),
35-
preset: args.preset || 'angular',
36+
preset: presetLoader(args),
3637
tagPrefix: args.tagPrefix
3738
}, context, { merges: null, path: args.path })
3839
.on('error', function (err) {

lib/preset-loader.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// TODO: this should be replaced with an object we maintain and
2+
// describe in: https://github.com/conventional-changelog/conventional-changelog-config-spec
3+
const spec = require('conventional-changelog-config-spec')
4+
5+
module.exports = (args) => {
6+
let preset = args.preset || 'conventionalcommits'
7+
if (preset === 'conventionalcommits') {
8+
preset = {
9+
name: preset
10+
}
11+
Object.keys(spec.properties).forEach(key => {
12+
if (args[key] !== undefined) preset[key] = args[key]
13+
})
14+
}
15+
return preset
16+
}

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "replacement for `npm version` with automatic CHANGELOG generation",
55
"bin": "bin/cli.js",
66
"scripts": {
7-
"pretest": "eslint .",
7+
"posttest": "eslint .",
88
"coverage": "nyc report --reporter=text-lcov | coveralls",
99
"test": "nyc mocha --timeout=20000 test.js",
1010
"release": "bin/cli.js"
@@ -39,12 +39,14 @@
3939
"homepage": "https://github.com/conventional-changelog/standard-version#readme",
4040
"dependencies": {
4141
"chalk": "^2.4.1",
42-
"conventional-changelog": "^3.0.6",
43-
"conventional-recommended-bump": "^4.0.4",
42+
"conventional-changelog": "^3.1.2",
43+
"conventional-changelog-config-spec": "^1.0.0",
44+
"conventional-recommended-bump": "^4.1.1",
4445
"detect-indent": "^5.0.0",
4546
"detect-newline": "^2.1.0",
4647
"dotgitignore": "^2.1.0",
4748
"figures": "^2.0.0",
49+
"find-up": "^3.0.0",
4850
"fs-access": "^1.0.0",
4951
"git-semver-tags": "^2.0.2",
5052
"semver": "^5.2.0",
@@ -53,7 +55,7 @@
5355
},
5456
"devDependencies": {
5557
"chai": "^3.5.0",
56-
"coveralls": "^3.0.1",
58+
"coveralls": "^3.0.3",
5759
"eslint": "^5.16.0",
5860
"eslint-config-standard": "^12.0.0",
5961
"eslint-plugin-import": "^2.16.0",

test.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,13 +668,13 @@ describe('cli', function () {
668668
})
669669

670670
it('does not display `all staged files` without the --commit-all flag', function () {
671-
var result = execCli()
671+
let result = execCli()
672672
result.code.should.equal(0)
673673
result.stdout.should.not.match(/and all staged files/)
674674
})
675675

676676
it('does display `all staged files` if the --commit-all flag is passed', function () {
677-
var result = execCli('--commit-all')
677+
let result = execCli('--commit-all')
678678
result.code.should.equal(0)
679679
result.stdout.should.match(/and all staged files/)
680680
})
@@ -989,4 +989,30 @@ describe('standard-version', function () {
989989
})
990990
})
991991
})
992+
993+
describe('configuration', () => {
994+
it('reads config from .versionrc', function () {
995+
// we currently skip several replacments in CHANGELOG
996+
// generation if repository URL isn't set.
997+
//
998+
// TODO: consider modifying this logic in conventional-commits
999+
// perhaps we should only skip the replacement if we rely on
1000+
// the {{host}} field?
1001+
writePackageJson('1.0.0', {
1002+
repository: {
1003+
url: 'https://github.com/yargs/yargs.git'
1004+
}
1005+
})
1006+
// write configuration that overrides default issue
1007+
// URL format.
1008+
fs.writeFileSync('.versionrc', JSON.stringify({
1009+
issueUrlFormat: 'http://www.foo.com/{{id}}'
1010+
}), 'utf-8')
1011+
commit('feat: another commit addresses issue #1')
1012+
execCli()
1013+
// CHANGELOG should have the new issue URL format.
1014+
const content = fs.readFileSync('CHANGELOG.md', 'utf-8')
1015+
content.should.include('http://www.foo.com/1')
1016+
})
1017+
})
9921018
})

0 commit comments

Comments
 (0)