├── .gitignore ├── .jscsrc ├── .jshintrc ├── .travis.yml ├── convention.md ├── index.js ├── package.json ├── readme.md ├── templates ├── commit.hbs ├── header.hbs └── template.hbs └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tmp 3 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "google", 3 | "maximumLineLength": null, 4 | "excludeFiles": ["node_modules/**"] 5 | } 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "eqnull": true, 6 | "immed": true, 7 | "latedef": true, 8 | "mocha" : true, 9 | "newcap": true, 10 | "noarg": true, 11 | "node": true, 12 | "sub": true, 13 | "undef": true, 14 | "unused": true 15 | } 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '5' 4 | - '4' 5 | - '3' 6 | - '2' 7 | - '1' 8 | - '0.12' 9 | - '0.10' 10 | before_script: 11 | - git config --global user.name 'Travis-CI' 12 | - git config --global user.email 'dummy@example.org' 13 | after_script: NODE_ENV=test istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage 14 | -------------------------------------------------------------------------------- /convention.md: -------------------------------------------------------------------------------- 1 | Make the changes to the code and tests and then commit to your branch. Be sure to follow the commit message conventions. 2 | 3 | Commit message summaries must follow this basic format: 4 | 5 | ``` 6 | Tag: Message (fixes #1234) 7 | ``` 8 | 9 | `Tag` should not be confused with git tag. 10 | `Message` should not be confused with git commit message. 11 | 12 | The `Tag` is one of the following: 13 | 14 | * `Fix` - for a bug fix. 15 | * `Update` - for a backwards-compatible enhancement. 16 | * `Breaking` - for a backwards-incompatible enhancement. 17 | * `Docs` - changes to documentation only. 18 | * `Build` - changes to build process only. 19 | * `New` - implemented a new feature. 20 | * `Upgrade` - for a dependency upgrade. 21 | 22 | The message summary should be a one-sentence description of the change. The issue number should be mentioned at the end. * The commit message should say "(fixes #1234)" at the end of the description if it closes out an existing issue (replace 1234 with the issue number). If the commit doesn't completely fix the issue, then use `(refs #1234)` instead of `(fixes #1234)`. 23 | 24 | Here are some good commit message summary examples: 25 | 26 | ``` 27 | Build: Update Travis to only test Node 0.10 (refs #734) 28 | Fix: Semi rule incorrectly flagging extra semicolon (fixes #840) 29 | Upgrade: Esprima to 1.2, switch to using Esprima comment attachment (fixes #730) 30 | ``` 31 | 32 | The commit message format is important because these messages are used to create a changelog for each release. The tag and issue number help to create more consistent and useful changelogs. 33 | 34 | Based on https://github.com/eslint/eslint.github.io/blob/master/docs/developer-guide/contributing.md#step-2-make-your-changes 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var Q = require('q'); 3 | var readFile = Q.denodeify(require('fs').readFile); 4 | var resolve = require('path').resolve; 5 | 6 | function presetOpts(cb) { 7 | var parserOpts = { 8 | headerPattern: /^(\w*)\: (.*?)(?:\((.*)\))?$/, 9 | headerCorrespondence: [ 10 | 'tag', 11 | 'message' 12 | ] 13 | }; 14 | 15 | var writerOpts = { 16 | transform: function(commit) { 17 | if (!commit.tag || typeof commit.tag !== 'string') { 18 | return; 19 | } 20 | 21 | return commit; 22 | }, 23 | groupBy: 'tag', 24 | commitGroupsSort: 'title', 25 | commitsSort: ['tag', 'message'] 26 | }; 27 | 28 | Q.all([ 29 | readFile(resolve(__dirname, 'templates/template.hbs'), 'utf-8'), 30 | readFile(resolve(__dirname, 'templates/header.hbs'), 'utf-8'), 31 | readFile(resolve(__dirname, 'templates/commit.hbs'), 'utf-8') 32 | ]) 33 | .spread(function(template, header, commit) { 34 | writerOpts.mainTemplate = template; 35 | writerOpts.headerPartial = header; 36 | writerOpts.commitPartial = commit; 37 | 38 | cb(null, { 39 | parserOpts: parserOpts, 40 | writerOpts: writerOpts 41 | }); 42 | }); 43 | } 44 | 45 | module.exports = presetOpts; 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conventional-changelog-eslint", 3 | "version": "0.1.0", 4 | "description": "conventional-changelog eslint preset", 5 | "main": "index.js", 6 | "scripts": { 7 | "coverage": "istanbul cover _mocha -- -R spec && rm -rf ./coverage", 8 | "lint": "jshint *.js --exclude node_modules && jscs *.js", 9 | "test": "mocha && npm run-script lint" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/stevemao/conventional-changelog-eslint.git" 14 | }, 15 | "keywords": [ 16 | "conventional-changelog", 17 | "eslint", 18 | "preset" 19 | ], 20 | "author": "Steve Mao", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/stevemao/conventional-changelog-eslint/issues" 24 | }, 25 | "homepage": "https://github.com/stevemao/conventional-changelog-eslint#readme", 26 | "devDependencies": { 27 | "chai": "^3.5.0", 28 | "conventional-changelog-core": "0.0.2", 29 | "coveralls": "^2.11.6", 30 | "istanbul": "^0.4.2", 31 | "jscs": "^2.9.0", 32 | "jshint": "^2.9.1", 33 | "mocha": "*", 34 | "shelljs": "^0.5.3", 35 | "through2": "^2.0.0" 36 | }, 37 | "dependencies": { 38 | "q": "^1.4.1" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage Status][coveralls-image]][coveralls-url] 2 | 3 | > [conventional-changelog](https://github.com/ajoslin/conventional-changelog) [eslint](https://github.com/eslint/eslint) preset 4 | 5 | 6 | See [convention](convention.md) 7 | 8 | 9 | [npm-image]: https://badge.fury.io/js/conventional-changelog-eslint.svg 10 | [npm-url]: https://npmjs.org/package/conventional-changelog-eslint 11 | [travis-image]: https://travis-ci.org/stevemao/conventional-changelog-eslint.svg?branch=master 12 | [travis-url]: https://travis-ci.org/stevemao/conventional-changelog-eslint 13 | [daviddm-image]: https://david-dm.org/stevemao/conventional-changelog-eslint.svg?theme=shields.io 14 | [daviddm-url]: https://david-dm.org/stevemao/conventional-changelog-eslint 15 | [coveralls-image]: https://coveralls.io/repos/stevemao/conventional-changelog-eslint/badge.svg 16 | [coveralls-url]: https://coveralls.io/r/stevemao/conventional-changelog-eslint 17 | -------------------------------------------------------------------------------- /templates/commit.hbs: -------------------------------------------------------------------------------- 1 | * {{#if message}}{{message}}{{else}}{{header}}{{/if}} 2 | 3 | {{~!-- commit hash --}} {{#if @root.linkReferences}}([{{hash}}]({{#if @root.host}}{{@root.host}}/{{/if}}{{#if @root.owner}}{{@root.owner}}/{{/if}}{{@root.repository}}/{{@root.commit}}/{{hash}})){{else}}{{hash~}}{{/if}} 4 | 5 | {{~!-- commit references --}}{{#if references}}, closes{{~#each references}} {{#if @root.linkReferences}}[{{#if this.owner}}{{this.owner}}/{{/if}}{{this.repository}}#{{this.issue}}]({{#if @root.host}}{{@root.host}}/{{/if}}{{#if this.repository}}{{#if this.owner}}{{this.owner}}/{{/if}}{{this.repository}}{{else}}{{#if @root.owner}}{{@root.owner}}/{{/if}}{{@root.repository}}{{/if}}/{{@root.issue}}/{{this.issue}}){{else}}{{#if this.owner}}{{this.owner}}/{{/if}}{{this.repository}}#{{this.issue}}{{/if}}{{/each}}{{/if}} 6 | -------------------------------------------------------------------------------- /templates/header.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{#if isPatch}}##{{else}}#{{/if}} {{#if @root.linkCompare}}[{{version}}]({{@root.host}}/{{#if @root.owner}}{{@root.owner}}/{{/if}}{{@root.repository}}/compare/{{previousTag}}...{{currentTag}}){{else}}{{version}}{{/if}}{{#if title}} "{{title}}"{{/if}}{{#if date}} ({{date}}){{/if}} 3 | -------------------------------------------------------------------------------- /templates/template.hbs: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 | {{#each commitGroups}} 4 | 5 | {{#if title}} 6 | ### {{title}} 7 | 8 | {{/if}} 9 | {{#each commits}} 10 | {{> commit root=@root}} 11 | {{/each}} 12 | {{/each}} 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var conventionalChangelogCore = require('conventional-changelog-core'); 3 | var config = require('./'); 4 | var expect = require('chai').expect; 5 | var shell = require('shelljs'); 6 | var through = require('through2'); 7 | var writeFileSync = require('fs').writeFileSync; 8 | 9 | describe('eslint preset', function() { 10 | before(function() { 11 | shell.config.silent = true; 12 | shell.rm('-rf', 'tmp'); 13 | shell.mkdir('tmp'); 14 | shell.cd('tmp'); 15 | shell.mkdir('git-templates'); 16 | shell.exec('git init --template=./git-templates'); 17 | 18 | writeFileSync('test1', ''); 19 | shell.exec('git add --all && git commit -m\'Fix: the `no-class-assign` rule (fixes #2718)\''); 20 | writeFileSync('test2', ''); 21 | shell.exec('git add --all && git commit -m"Update: Handle CRLF line endings in spaced-comment rule - 2 (fixes #3005)"'); 22 | writeFileSync('test3', ''); 23 | shell.exec('git add --all && git commit -m"Fix: indent rule should recognize single line statements with ASI (fixes #3001, fixes #3000)"'); 24 | writeFileSync('test4', ''); 25 | shell.exec('git add --all && git commit -m"Docs: Fix unmatched paren in rule description"'); 26 | writeFileSync('test5', ''); 27 | shell.exec('git add --all && git commit -m"Merge pull request #3033 from gcochard/patch-3 "'); 28 | }); 29 | 30 | it('should work if there is no semver tag', function(done) { 31 | conventionalChangelogCore({ 32 | config: config 33 | }) 34 | .on('error', function(err) { 35 | done(err); 36 | }) 37 | .pipe(through(function(chunk) { 38 | chunk = chunk.toString(); 39 | 40 | expect(chunk).to.include('the `no-class-assign` rule'); 41 | expect(chunk).to.include('### Fix'); 42 | expect(chunk).to.include('indent rule should recognize single line statements with ASI'); 43 | expect(chunk).to.include('### Docs'); 44 | 45 | expect(chunk).to.not.include('3033'); 46 | 47 | done(); 48 | })); 49 | }); 50 | }); 51 | --------------------------------------------------------------------------------