Skip to content
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

feat: adds new configurable conventionalcommits preset #323

Merged
merged 15 commits into from May 5, 2019
33 changes: 33 additions & 0 deletions README.md
Expand Up @@ -65,6 +65,39 @@ Now you can use `standard-version` in place of `npm version`.

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

## Configuration

You can configure `standard-version` either by:

1. Placing a `standard-version` stanza in your `package.json` (assuming
your project is JavaScript).
1. Creating a `.versionrc` or `.versionrc.json`.

Any of the command line paramters accepted by `standard-version` can instead
be provided via configuration.

### Customizing CHANGELOG Generation

By default, `standard-version` uses the [conventionalcommits preset](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits).

This preset:

* adheres closely to the [conventionalcommits.org](https://www.conventionalcommits.org)
specification.
* is highly configurable, following the configuration specification
[maintained here](https://github.com/conventional-changelog/conventional-changelog-config-spec).
* _we've documented these config settings as a recommendation to other tooling makers._

There are a variety of dials and knobs you can turn related to CHANGELOG generation.

As an example, suppose you're using GitLab, rather than GitHub, you might modify the following variables:

* `commitUrlFormat`: the URL format of commit SHAs detected in commit messages.
* `compareUrlFormat`: the URL format used to compare two tags.
* `issueUrlFormat`: the URL format used to link to issues.

Making these URLs match GitLab's format, rather than GitHub's.

## CLI Usage

### First Release
Expand Down
28 changes: 24 additions & 4 deletions command.js
@@ -1,6 +1,12 @@
let defaults = require('./defaults')
const findUp = require('find-up')
const defaults = require('./defaults')
const { readFileSync } = require('fs')

module.exports = require('yargs')
const configPath = findUp.sync(['.versionrc', '.version.json'])
const config = configPath ? JSON.parse(readFileSync(configPath)) : {}
const spec = require('conventional-changelog-config-spec')

const yargs = require('yargs')
.usage('Usage: $0 [options]')
.option('release-as', {
alias: 'r',
Expand Down Expand Up @@ -95,11 +101,25 @@ module.exports = require('yargs')
return true
}
})
.version()
.alias('version', 'v')
.help()
.alias('help', 'h')
.example('$0', 'Update changelog and tag release')
.example('$0 -m "%s: see changelog for details"', 'Update changelog and tag release with custom commit message')
.pkgConf('standard-version')
.config(config)
.wrap(97)

Object.keys(spec.properties).forEach(propertyKey => {
const property = spec.properties[propertyKey]
yargs.option(propertyKey, {
type: property.type,
describe: property.description,
default: property.default,
group: 'Preset Configuration:'
})
})

module.exports = yargs

// TODO: yargs should be populated with keys/descriptions from
// https://github.com/conventional-changelog/conventional-changelog-config-spec
4 changes: 2 additions & 2 deletions defaults.json
Expand Up @@ -11,5 +11,5 @@
"skip": {},
"dryRun": false,
"gitTagFallback": true,
"preset": "angular"
}
"preset": "conventionalcommits"
}
3 changes: 2 additions & 1 deletion lib/lifecycles/bump.js
Expand Up @@ -9,6 +9,7 @@ const figures = require('figures')
const fs = require('fs')
const DotGitignore = require('dotgitignore')
const path = require('path')
const presetLoader = require('../preset-loader')
const runLifecycleScript = require('../run-lifecycle-script')
const semver = require('semver')
const stringifyPackage = require('stringify-package')
Expand Down Expand Up @@ -137,7 +138,7 @@ function bumpVersion (releaseAs, args) {
} else {
conventionalRecommendedBump({
debug: args.verbose && console.info.bind(console, 'conventional-recommended-bump'),
preset: args.preset || 'angular',
preset: presetLoader(args),
path: args.path
}, function (err, release) {
if (err) return reject(err)
Expand Down
3 changes: 2 additions & 1 deletion lib/lifecycles/changelog.js
Expand Up @@ -3,6 +3,7 @@ const chalk = require('chalk')
const checkpoint = require('../checkpoint')
const conventionalChangelog = require('conventional-changelog')
const fs = require('fs')
const presetLoader = require('../preset-loader')
const runLifecycleScript = require('../run-lifecycle-script')
const writeFile = require('../write-file')

Expand Down Expand Up @@ -32,7 +33,7 @@ function outputChangelog (args, newVersion) {
if (args.dryRun) context = { version: newVersion }
let changelogStream = conventionalChangelog({
debug: args.verbose && console.info.bind(console, 'conventional-changelog'),
preset: args.preset || 'angular',
preset: presetLoader(args),
tagPrefix: args.tagPrefix
}, context, { merges: null, path: args.path })
.on('error', function (err) {
Expand Down
16 changes: 16 additions & 0 deletions lib/preset-loader.js
@@ -0,0 +1,16 @@
// TODO: this should be replaced with an object we maintain and
// describe in: https://github.com/conventional-changelog/conventional-changelog-config-spec
const spec = require('conventional-changelog-config-spec')

module.exports = (args) => {
let preset = args.preset || 'conventionalcommits'
if (preset === 'conventionalcommits') {
preset = {
name: preset
}
Object.keys(spec.properties).forEach(key => {
if (args[key] !== undefined) preset[key] = args[key]
})
}
return preset
}
10 changes: 6 additions & 4 deletions package.json
Expand Up @@ -4,7 +4,7 @@
"description": "replacement for `npm version` with automatic CHANGELOG generation",
"bin": "bin/cli.js",
"scripts": {
"pretest": "eslint .",
"posttest": "eslint .",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"test": "nyc mocha --timeout=20000 test.js",
"release": "bin/cli.js"
Expand Down Expand Up @@ -39,12 +39,14 @@
"homepage": "https://github.com/conventional-changelog/standard-version#readme",
"dependencies": {
"chalk": "^2.4.1",
"conventional-changelog": "^3.0.6",
"conventional-recommended-bump": "^4.0.4",
"conventional-changelog": "^3.1.2",
"conventional-changelog-config-spec": "^1.0.0",
"conventional-recommended-bump": "^4.1.1",
"detect-indent": "^5.0.0",
"detect-newline": "^2.1.0",
"dotgitignore": "^2.1.0",
"figures": "^2.0.0",
"find-up": "^3.0.0",
"fs-access": "^1.0.0",
"git-semver-tags": "^2.0.2",
"semver": "^5.2.0",
Expand All @@ -53,7 +55,7 @@
},
"devDependencies": {
"chai": "^3.5.0",
"coveralls": "^3.0.1",
"coveralls": "^3.0.3",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.16.0",
Expand Down
30 changes: 28 additions & 2 deletions test.js
Expand Up @@ -668,13 +668,13 @@ describe('cli', function () {
})

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

it('does display `all staged files` if the --commit-all flag is passed', function () {
var result = execCli('--commit-all')
let result = execCli('--commit-all')
result.code.should.equal(0)
result.stdout.should.match(/and all staged files/)
})
Expand Down Expand Up @@ -989,4 +989,30 @@ describe('standard-version', function () {
})
})
})

describe('configuration', () => {
it('reads config from .versionrc', function () {
// we currently skip several replacments in CHANGELOG
// generation if repository URL isn't set.
//
// TODO: consider modifying this logic in conventional-commits
// perhaps we should only skip the replacement if we rely on
// the {{host}} field?
writePackageJson('1.0.0', {
repository: {
url: 'https://github.com/yargs/yargs.git'
}
})
// write configuration that overrides default issue
// URL format.
fs.writeFileSync('.versionrc', JSON.stringify({
issueUrlFormat: 'http://www.foo.com/{{id}}'
}), 'utf-8')
commit('feat: another commit addresses issue #1')
execCli()
// CHANGELOG should have the new issue URL format.
const content = fs.readFileSync('CHANGELOG.md', 'utf-8')
content.should.include('http://www.foo.com/1')
})
})
})