├── .babelrc ├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── convention.js ├── package.json ├── src └── index.js ├── templates ├── commit.hbs ├── footer.hbs ├── header.hbs └── template.hbs └── test ├── body.js ├── footer.js └── header.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["espower", "transform-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: kazupon 4 | patreon: kazupon 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | .DS_Store 4 | *.log 5 | *.gz 6 | *.swp 7 | *~ 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # [2.0.0](https://github.com/kazupon/git-commit-message-convention/compare/v1.2.0...v2.0.0) (2019-11-29) 3 | 4 | 5 | ### :star: New Features 6 | 7 | * emoji :twisted_rightwards_arrows: for merge conflict resolution ([b305fe3](https://github.com/kazupon/git-commit-message-convention/commit/b305fe3)) 8 | 9 | 10 | ### :boom: Breaking changes 11 | 12 | * dependency to deps ([1485b28](https://github.com/kazupon/git-commit-message-convention/commit/1485b28)) 13 | 14 | 15 | ### :bug: Bug Fixes 16 | 17 | * Fix :copyright: license emoji code ([#5](https://github.com/kazupon/git-commit-message-convention/issues/5)) by [@anselal](https://github.com/anselal) ([0ba5929](https://github.com/kazupon/git-commit-message-convention/commit/0ba5929)), closes [#5](https://github.com/kazupon/git-commit-message-convention/issues/5) 18 | 19 | 20 | 21 | # [1.2.0](https://github.com/kazupon/git-commit-message-convention/compare/v1.1.0...v1.2.0) (2016-07-13) 22 | 23 | 24 | ### :boom: Breaking changes 25 | 26 | * **README:** change wip commit type ([51206e0](https://github.com/kazupon/git-commit-message-convention/commit/51206e0)) 27 | 28 | 29 | ### :zap: Improvements 30 | 31 | * **convention:** add update group to release note enumration ([ea64fbe](https://github.com/kazupon/git-commit-message-convention/commit/ea64fbe)) 32 | 33 | 34 | ### :up: Updates 35 | 36 | * **README:** add green heart emoji case ([5fa8562](https://github.com/kazupon/git-commit-message-convention/commit/5fa8562)) 37 | * **README:** change initial commit type ([eaa0f99](https://github.com/kazupon/git-commit-message-convention/commit/eaa0f99)) 38 | 39 | 40 | 41 | # [1.1.0](https://github.com/kazupon/git-commit-message-convention/compare/v1.0.0...v1.1.0) (2016-06-13) 42 | 43 | 44 | ### :zap: Improvements 45 | 46 | * **emoji:** add update emoji ([04a9c66](https://github.com/kazupon/git-commit-message-convention/commit/04a9c66)) 47 | 48 | 49 | 50 | 51 | # [1.0.0](https://github.com/kazupon/git-commit-message-convention/compare/v0.0.4...v1.0.0) (2016-06-13) 52 | 53 | 54 | 55 | 56 | ## [0.0.4](https://github.com/kazupon/git-commit-message-convention/compare/v0.0.2...v0.0.4) (2016-06-06) 57 | 58 | 59 | ### :bug: Bug Fixes 60 | 61 | * fix typo ([34782dc](https://github.com/kazupon/git-commit-message-convention/commit/34782dc)) 62 | * **convention:** fix bug fix listup issue ([3b96930](https://github.com/kazupon/git-commit-message-convention/commit/3b96930)) 63 | 64 | 65 | 66 | 67 | ## [0.0.4](https://github.com/kazupon/git-commit-message-convention/compare/v0.0.2...v0.0.4) (2016-06-06) 68 | 69 | 70 | ### :bug: Bug Fixes 71 | 72 | * fix typo ([34782dc](https://github.com/kazupon/git-commit-message-convention/commit/34782dc)) 73 | * **convention:** fix bug fix listup issue ([3b96930](https://github.com/kazupon/git-commit-message-convention/commit/3b96930)) 74 | 75 | 76 | 77 | 78 | ## [0.0.3](https://github.com/kazupon/git-commit-message-convention/compare/v0.0.2...v0.0.3) (2016-05-10) 79 | 80 | ### :bug: Bug Fixes 81 | 82 | * fix typo ([34782dc](https://github.com/kazupon/git-commit-message-convention/commit/34782dc)] 83 | 84 | 85 | ## [0.0.2](https://github.com/kazupon/git-commit-message-convention/compare/v0.0.1...v0.0.2) (2016-05-02) 86 | 87 | 88 | ### :star: New Features 89 | 90 | * **conventional-changelog:** add conventional-changelog preset ([1409bc2](https://github.com/kazupon/git-commit-message-convention/commit/1409bc2)) 91 | 92 | 93 | 94 | 95 | ## [0.0.1](https://github.com/kazupon/git-commit-message-convention/compare/db67825...v0.0.1) (2016-05-02) 96 | 97 | 98 | ### :boom: Breaking changes 99 | 100 | * remove notes ([29f025b](https://github.com/kazupon/git-commit-message-convention/commit/29f025b)) 101 | 102 | 103 | ### :star: New Features 104 | 105 | * define commit log convention ([db67825](https://github.com/kazupon/git-commit-message-convention/commit/db67825)) 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 kazuya kawaguchi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # git-commit-message-convention 2 | 3 | Extend git commit message from angular style 4 | 5 | 6 | # Commit Message Format 7 | All Commit Message Format **MUST** meet this Text Format: 8 | 9 | ``` 10 | [:: ][[()]: ] 11 | [] 12 | [] 13 | [] 14 | [] 15 | ``` 16 | 17 | 18 | # Types 19 | 20 | | Type | Description | 21 | |:-------------:|-------------| 22 | | `new` | for new feature implementing commit| 23 | | `feature` | for new feature implementing commit (equal `new`) | 24 | | `update` | for update commit | 25 | | `bug` | for bug fix commit | 26 | | `security` | for security issue fix commit | 27 | | `performance` | for performance issue fix commit | 28 | | `improvement` | for backwards-compatible enhancement commit | 29 | | `breaking` | for backwards-incompatible enhancement commit | 30 | | `deprecated` | for deprecated feature commit | 31 | | `i18n` | for i18n (internationalization) commit | 32 | | `a11y` | for a11y (accessibility) commit | 33 | | `refactor` | for refactoring commit | 34 | | `docs` | for documentation commit | 35 | | `example` | for example code commit | 36 | | `test` | for testing commit | 37 | | `deps` | for dependencies upgrading or downgrading commit | 38 | | `config` | for configuration commit | 39 | | `build` | for packaging or bundling commit | 40 | | `release` | for publishing commit | 41 | | `wip` | for work in progress commit | 42 | | `chore` | for other operations commit | 43 | 44 | 45 | If the prefix is the below types, it will appear in the changelog. 46 | 47 | - `new` (`feature`) 48 | - `bug` 49 | - `performance` 50 | - `security` 51 | - `improvement` 52 | - `deprecated` 53 | - `breaking` 54 | 55 | 56 | # Scope 57 | The scope could be anything specifying place or category of the commit change. For example $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, feature1, etc... 58 | 59 | 60 | # Subject 61 | The subject contains succinct description of the change: 62 | 63 | * use the imperative, present tense: "change" not "changed" nor "changes" 64 | * don't capitalize first letter 65 | * no dot (.) at the end 66 | 67 | 68 | # Message Body 69 | Just as in the **Subject**, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior. 70 | 71 | 72 | # Message Footer 73 | The Message Footer should contain any information about **Notes** and also Message Footer should be **recommended** [GitHub Issue](https://github.com/features#issues) ID Reference, Ex. `Issue #27`, `Fixes #1`, `Closes #2`, `Resolves #3`. 74 | 75 | **Notes** should start with the word `NOTE:` with a space or two newlines. The rest of the commit message is then used for this. 76 | 77 | 78 | # Revert 79 | If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted commit. In the body it should say: This reverts commit ., where the hash is the SHA of the commit being reverted. 80 | 81 | 82 | # Emojis 83 | 84 | | Emoji | Raw Emoji Code | Type | Description | 85 | |:-----------------------------:|---------------------------------|--------------------|-------------| 86 | | :star: | `:star:` | `new` or `feature` | add **new feature** | 87 | | :bug: | `:bug:` | `bug` | fix **bug** issue | 88 | | :ambulance: | `:ambulance:` | `bug` | critical hotfix **bug** issue | 89 | | :lock: | `:lock:` | `security` | fix **security** issue | 90 | | :chart_with_upwards_trend: | `:chart_with_upwards_trend:` | `performance` | fix **performance** issue | 91 | | :zap: | `:zap:` | `improvement` | update **backwards-compatible** feature | 92 | | :boom: | `:boom` | `breaking` | update **backwards-incompatible** feature | 93 | | :warning: | `:warning:` | `deprecated` | **deprecate** feature | 94 | | :globe_with_meridians: | `:globe_with_meridians:` | `i18n` | update or fix **internationalization** | 95 | | :wheelchair: | `:wheelchair:` | `a11y` | update or fix **accessibility** | 96 | | :rotating_light: | `:rotating_light:` | `refactor` | remove **linter**/strict/deprecation warnings | 97 | | :shirt: | `:shirt:` | `refactor` | **refactoring** or code **layouting** | 98 | | :white_check_mark: | `:white_check_mark:` | `test` | add **tests**, fix **tests** failur or **CI** building | 99 | | :pencil: | `:pencil:` | `docs` | update **documentation** | 100 | | :copyright: | `:copyright:` | `docs` | decide or change **license** | 101 | | :lollipop: | `:lollipop:` | `example` | for **example** or **demo** codes | 102 | | :lipstick: | `:lipstick:` | `update` | update **UI/Cosmetic** | 103 | | :up: | `:up:` | `update` | update **other** | 104 | | :truck: | `:truck:` | `update` | **move** or **rename** files, repository, ... | 105 | | :twisted_rightwards_arrows:| `:twisted_rightwards_arrows:`| `update` | merge **conflict resolution** | 106 | | :heavy_plus_sign: | `:heavy_plus_sign:` | `update` | **add** files, dependencies, ... | 107 | | :heavy_minus_sign: | `:heavy_minus_sign:` | `update` | **remove** files, dependencies, ... | 108 | | :on: | `:on:` | `update` | **enable** feature and something ... | 109 | | :arrow_up: | `:arrow_up:` | `deps` | upgrade **dependencies** | 110 | | :arrow_down: | `:arrow_down:` | `deps` | downgrade **dependencies** | 111 | | :pushpin: | `:pushpin:` | `deps` | pin **dependencies** | 112 | | :wrench: | `:wrench:` | `config` | update **configuration** | 113 | | :package: | `:package:` | `build` | **packaging** or **bundling** or **building** | 114 | | :whale: | `:whale:` | `build` | Dockerfile | 115 | | :hatching_chick: | `:hatching_chick:` | `release` | **initial** commit | 116 | | :confetti_ball: | `:confetti_ball:` | `release` | release **major** version | 117 | | :tada: | `:tada:` | `release` | release **minor** version | 118 | | :sparkles: | `:sparkles:` | `release` | release **patch** version | 119 | | :rocket: | `:rocket:` | `release` | **deploy** to production enviroment | 120 | | :bookmark: | `:bookmark:` | `release` | **tagged** with version label | 121 | | :back: | `:back:` | `revert` | **revert** commiting | 122 | | :construction: | `:construction:` | `wip` | **WIP** commiting | 123 | 124 | 125 | Ask to Be [Creative](http://www.emoji-cheat-sheet.com/)! 126 | 127 | 128 | # Examples 129 | 130 | new: 131 | ``` 132 | :star: new(graphite): add 'graphiteWidth' option 133 | ``` 134 | 135 | bug fix: 136 | ``` 137 | :bug: fix(graphite): stop graphite breaking when width < 0.1 138 | 139 | Closes #28 140 | ``` 141 | 142 | improve performance: 143 | ``` 144 | :chart_with_upwards_trend: performance(graphite): remove graphiteWidth option 145 | 146 | The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason. 147 | ``` 148 | 149 | revert: 150 | ``` 151 | :back: revert: new: add 'graphiteWidth' option 152 | 153 | This reverts commit 667ecc1654a317a13331b17617d973392f415f02. 154 | ``` 155 | 156 | # Support tools 157 | 158 | ## conventional-changelog 159 | 160 | You can use with `conventional-changelog-cli` and `conventional-github-releaser`. 161 | 162 | e.g. conventional-changelog-cli: 163 | 164 | $ npm i --save-dev git://github.com/kazupon/git-commit-message-convention.git 165 | $ conventional-changelog -i CHANGELOG.md -s -n ./node_modules/git-commit-message-convention/convention.js -r 0 166 | 167 | e.g. conventional-github-releaser: 168 | 169 | $ conventional-github-releaser -n ./node_modules/git-commit-message-convention/convention.js -r 0 170 | 171 | 172 | # TODO 173 | - [x] support conventional commit tools (e.g. conventional-changelog) 174 | - [ ] lint 175 | - [ ] cli 176 | - [ ] create a conventional commit tools with `golang` 177 | 178 | 179 | # License 180 | 181 | ## MIT 182 | 183 | [MIT](http://opensource.org/licenses/MIT) 184 | -------------------------------------------------------------------------------- /convention.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var readFileSync = require('fs').readFileSync; 3 | var compareFunc = require('compare-func'); 4 | var resolve = require('path').resolve; 5 | var path = require('path'); 6 | var pkgJson = {}; 7 | var gufg = require('github-url-from-git'); 8 | try { 9 | pkgJson = require(path.resolve( 10 | process.cwd(), 11 | './package.json' 12 | )); 13 | } catch (err) { 14 | console.error('no root package.json found'); 15 | } 16 | 17 | var parserOpts = { 18 | headerPattern: /^(?:\:(\w*)\: )?(?:(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: )?(.*)$/, 19 | headerCorrespondence: ['emoji', 'type', 'scope', 'subject'], 20 | noteKeywords: ['NOTE'], 21 | revertPattern: /^revert:\s([\s\S]*?)\s*This reverts commit (\w*)\./, 22 | revertCorrespondence: ['header', 'hash'] 23 | }; 24 | 25 | function issueUrl() { 26 | var url = null; 27 | if (pkgJson.repository && pkgJson.repository.url && ~pkgJson.repository.url.indexOf('github.com')) { 28 | var gitUrl = gufg(pkgJson.repository.url); 29 | 30 | if (gitUrl) { 31 | return gitUrl + '/issues/'; 32 | } else { 33 | return url; 34 | } 35 | } 36 | } 37 | 38 | 39 | 40 | var parserOpts = { 41 | headerPattern: /^(?:\:(\w*)\: )?(?:(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: )?(.*)$/, 42 | headerCorrespondence: ['emoji', 'type', 'scope', 'subject'], 43 | noteKeywords: ['NOTE'] 44 | }; 45 | 46 | var writerOpts = { 47 | transform: function (commit) { 48 | if (commit.type === 'new') { 49 | commit.type = ':star: New Features'; 50 | } else if (commit.type === 'feature') { 51 | commit.type = ':star: New Features'; 52 | } else if (commit.type === 'bug') { 53 | commit.type = ':bug: Bug Fixes'; 54 | } else if (commit.type === 'update') { 55 | commit.type = ':up: Updates'; 56 | } else if (commit.type === 'improvement') { 57 | commit.type = ':zap: Improvements'; 58 | } else if (commit.type === 'performance') { 59 | commit.type = ':chart_with_upwards_trend: Performance Fixes'; 60 | } else if (commit.type === 'security') { 61 | commit.type = ':lock: Security Fixes'; 62 | } else if (commit.type === 'deprecated') { 63 | commit.type = ':warning: Deprecated'; 64 | } else if (commit.type === 'breaking') { 65 | commit.type = ':boom: Breaking changes'; 66 | } else if (commit.type === 'revert') { 67 | commit.type = ':back: Reverts'; 68 | } else { 69 | return; 70 | } 71 | 72 | if (commit.scope === '*') { 73 | commit.scope = ''; 74 | } 75 | 76 | if (typeof commit.hash === 'string') { 77 | commit.hash = commit.hash.substring(0, 7); 78 | } 79 | 80 | if (typeof commit.subject === 'string') { 81 | var url = issueUrl(); 82 | if (url) { 83 | // GitHub issue URLs. 84 | commit.subject = commit.subject.replace(/( ?)#([0-9]+)(\b|^)/g, '$1[#$2](' + url + '$2)$3'); 85 | } 86 | // GitHub user URLs. 87 | commit.subject = commit.subject.replace(/( ?)@([a-zA-Z0-9_]+)(\b|^)/g, '$1[@$2](https://github.com/$2)$3'); 88 | commit.subject = commit.subject; 89 | } 90 | 91 | return commit; 92 | }, 93 | groupBy: 'type', 94 | commitGroupsSort: 'title', 95 | commitsSort: ['scope', 'subject'], 96 | noteGroupsSort: 'title', 97 | notesSort: compareFunc 98 | }; 99 | 100 | writerOpts.mainTemplate = readFileSync(resolve(__dirname, 'templates/template.hbs'), 'utf-8'); 101 | writerOpts.headerPartial = readFileSync(resolve(__dirname, 'templates/header.hbs'), 'utf-8'); 102 | writerOpts.commitPartial = readFileSync(resolve(__dirname, 'templates/commit.hbs'), 'utf-8'); 103 | writerOpts.footerPartial = readFileSync(resolve(__dirname, 'templates/footer.hbs'), 'utf-8'); 104 | 105 | module.exports = { 106 | parserOpts: parserOpts, 107 | writerOpts: writerOpts 108 | }; 109 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "git-commit-message-convention", 3 | "description": "Extend git commit message from angular style", 4 | "version": "2.0.0", 5 | "author": { 6 | "name": "kazuya kawaguchi", 7 | "email": "kawakazu80@gmail.com" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/kazupon/git-commit-message-convention/issues" 11 | }, 12 | "dependencies": { 13 | "compare-func": "^1.3.1", 14 | "github-url-from-git": "^1.4.0" 15 | }, 16 | "devDependencies": { 17 | "ava": "^0.14.0", 18 | "babel-cli": "^6.7.7", 19 | "babel-preset-es2015": "^6.6.0", 20 | "conventional-changelog-cli": "^1.1.1", 21 | "conventional-commits-parser": "^1.2.0", 22 | "conventional-github-releaser": "^1.1.3" 23 | }, 24 | "homepage": "https://github.com/kazupon/git-commit-message-convention", 25 | "license": "MIT", 26 | "main": "index.js", 27 | "private": true, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/kazupon/git-commit-message-convention.git" 31 | }, 32 | "scripts": { 33 | "build": "babel src -d lib", 34 | "changelog": "conventional-changelog -i CHANGELOG.md -s -n ./convention.js", 35 | "release": "conventional-github-releaser -n ./convention.js", 36 | "test": "ava --require babel-register" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export const REGEX_HEADER_PATTERN = /^(?:\:(\w*)\: )?(?:(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: )?(.*)$/ 2 | export const REGEX_HEADER_CORRESPONDENCE = ['emoji', 'type', 'scope', 'subject'] 3 | export const REGEX_NOTE_KEYWORDS = ['NOTE'] 4 | -------------------------------------------------------------------------------- /templates/commit.hbs: -------------------------------------------------------------------------------- 1 | *{{#if scope}} **{{scope}}:** 2 | {{~/if}} {{#if subject}} 3 | {{~subject}} 4 | {{~else}} 5 | {{~header}} 6 | {{~/if}} 7 | 8 | {{~!-- commit link --}} {{#if @root.linkReferences~}} 9 | ([{{hash}}]( 10 | {{~#if @root.host}} 11 | {{~@root.host}}/ 12 | {{~/if}} 13 | {{~#if @root.owner}} 14 | {{~@root.owner}}/ 15 | {{~/if}} 16 | {{~@root.repository}}/{{@root.commit}}/{{hash}})) 17 | {{~else}} 18 | {{~hash}} 19 | {{~/if}} 20 | 21 | {{~!-- commit references --}} 22 | {{~#if references~}} 23 | , closes 24 | {{~#each references}} {{#if @root.linkReferences}}[ 25 | {{~#if this.owner}} 26 | {{~this.owner}}/ 27 | {{~/if}} 28 | {{~this.repository}}#{{this.issue}}]( 29 | {{~#if @root.host}} 30 | {{~@root.host}}/ 31 | {{~/if}} 32 | {{~#if this.repository}} 33 | {{~#if this.owner}} 34 | {{~this.owner}}/ 35 | {{~/if}} 36 | {{~this.repository}} 37 | {{~else}} 38 | {{~#if @root.owner}} 39 | {{~@root.owner}}/ 40 | {{~/if}} 41 | {{~@root.repository}} 42 | {{~/if~}} 43 | /{{@root.issue}}/{{this.issue}}) 44 | {{~else}} 45 | {{~#if this.owner}} 46 | {{~this.owner}}/ 47 | {{~/if}} 48 | {{~this.repository}}#{{this.issue}} 49 | {{~/if}}{{/each}} 50 | {{~/if}} 51 | 52 | -------------------------------------------------------------------------------- /templates/footer.hbs: -------------------------------------------------------------------------------- 1 | {{#if noteGroups}} 2 | {{#each noteGroups}} 3 | 4 | ### {{title}} 5 | 6 | {{#each notes}} 7 | * {{#if commit.scope}}{{commit.scope}}: {{/if}}{{text}} 8 | {{/each}} 9 | {{/each}} 10 | 11 | {{/if}} 12 | -------------------------------------------------------------------------------- /templates/header.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{#if isPatch~}} 3 | ## 4 | {{~else~}} 5 | # 6 | {{~/if}} {{#if @root.linkCompare~}} 7 | [{{version}}]( 8 | {{~#if @root.host}} 9 | {{~@root.host}}/ 10 | {{~/if}} 11 | {{~#if @root.owner}} 12 | {{~@root.owner}}/ 13 | {{~/if}} 14 | {{~@root.repository}}/compare/{{previousTag}}...{{currentTag}}) 15 | {{~else}} 16 | {{~version}} 17 | {{~/if}} 18 | {{~#if title}} "{{title}}" 19 | {{~/if}} 20 | {{~#if date}} ({{date}}) 21 | {{/if}} 22 | -------------------------------------------------------------------------------- /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 | 13 | {{/each}} 14 | {{> footer}} 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/body.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import parser from 'conventional-commits-parser' 3 | import {REGEX_HEADER_PATTERN, REGEX_HEADER_CORRESPONDENCE } from '../src/index.js' 4 | 5 | const options = { 6 | headerPattern: REGEX_HEADER_PATTERN, 7 | headerCorrespondence: REGEX_HEADER_CORRESPONDENCE 8 | } 9 | 10 | 11 | test('basic', (t) => { 12 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)\n' 13 | + '\n' 14 | + 'this is the body' 15 | let parsed = parser.sync(commit, options) 16 | t.is(parsed.body, 'this is the body') 17 | }) 18 | 19 | test('nothing', (t) => { 20 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)' 21 | let parsed = parser.sync(commit, options) 22 | t.falsy(parsed.body) 23 | }) 24 | 25 | test('with footer', (t) => { 26 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)\n' 27 | + '\n' 28 | + 'this is the body' 29 | + '\n' 30 | + 'BREAKING CHANGE:' 31 | + 'this is breaking change' 32 | let parsed = parser.sync(commit, options) 33 | t.is(parsed.body, 'this is the body') 34 | }) 35 | -------------------------------------------------------------------------------- /test/footer.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import parser from 'conventional-commits-parser' 3 | import { REGEX_HEADER_PATTERN, REGEX_HEADER_CORRESPONDENCE, REGEX_NOTE_KEYWORDS } from '../src/index.js' 4 | 5 | const options = { 6 | headerPattern: REGEX_HEADER_PATTERN, 7 | headerCorrespondence: REGEX_HEADER_CORRESPONDENCE, 8 | noteKeywords: REGEX_NOTE_KEYWORDS 9 | } 10 | 11 | 12 | test('basic', (t) => { 13 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)\n' 14 | + '\n' 15 | + 'this is the body\n' 16 | + '\n' 17 | + 'NOTE:\n' 18 | + 'this is the note\n' 19 | + '\n' 20 | + 'Closes #1' 21 | let parsed = parser.sync(commit, options) 22 | t.is(parsed.footer, 'NOTE:\nthis is the note\n\nCloses #1') 23 | }) 24 | 25 | test('notes: note', (t) => { 26 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)\n' 27 | + '\n' 28 | + 'NOTE:\n' 29 | + 'this is note ...' 30 | let parsed = parser.sync(commit, options) 31 | t.deepEqual(parsed.notes, [{ title: 'NOTE', text: 'this is note ...' }]) 32 | }) 33 | 34 | test('notes: undefined note', (t) => { 35 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)\n' 36 | + '\n' 37 | + 'TODO:\n' 38 | + 'this is note ...' 39 | let parsed = parser.sync(commit, options) 40 | t.deepEqual(parsed.notes, []) 41 | }) 42 | -------------------------------------------------------------------------------- /test/header.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import parser from 'conventional-commits-parser' 3 | import { REGEX_HEADER_PATTERN, REGEX_HEADER_CORRESPONDENCE } from '../src/index.js' 4 | 5 | const options = { 6 | headerPattern: REGEX_HEADER_PATTERN, 7 | headerCorrespondence: REGEX_HEADER_CORRESPONDENCE 8 | } 9 | 10 | 11 | test('full', (t) => { 12 | let commit = ':bug: fix(chat): broadcast $destroy event on scope destruction (by @kazupon)' 13 | let parsed = parser.sync(commit, options) 14 | t.is(parsed.emoji, 'bug') 15 | t.is(parsed.type, 'fix') 16 | t.is(parsed.scope, 'chat') 17 | t.is(parsed.subject, 'broadcast $destroy event on scope destruction (by @kazupon)') 18 | }) 19 | 20 | test('abbreve emoji', (t) => { 21 | let commit = 'fix(chat): broadcast $destroy event on scope destruction (by @kazupon)' 22 | let parsed = parser.sync(commit, options) 23 | t.falsy(parsed.emoji) 24 | t.is(parsed.type, 'fix') 25 | t.is(parsed.scope, 'chat') 26 | t.is(parsed.subject, 'broadcast $destroy event on scope destruction (by @kazupon)') 27 | }) 28 | 29 | test('abbreve type', (t) => { 30 | let commit = ':bug: broadcast $destroy event on scope destruction (by @kazupon)' 31 | let parsed = parser.sync(commit, options) 32 | t.is(parsed.emoji, 'bug') 33 | t.falsy(parsed.type) 34 | t.falsy(parsed.scope) 35 | t.is(parsed.subject, 'broadcast $destroy event on scope destruction (by @kazupon)') 36 | }) 37 | 38 | test('abbreve scope', (t) => { 39 | let commit = ':bug: fix: broadcast $destroy event on scope destruction (by @kazupon)' 40 | let parsed = parser.sync(commit, options) 41 | t.is(parsed.emoji, 'bug') 42 | t.is(parsed.type, 'fix') 43 | t.falsy(parsed.scope) 44 | t.is(parsed.subject, 'broadcast $destroy event on scope destruction (by @kazupon)') 45 | }) 46 | 47 | test('subject only', (t) => { 48 | let commit = 'broadcast $destroy event on scope destruction (by @kazupon)' 49 | let parsed = parser.sync(commit, options) 50 | t.falsy(parsed.emoji) 51 | t.falsy(parsed.type) 52 | t.falsy(parsed.scope) 53 | t.is(parsed.subject, 'broadcast $destroy event on scope destruction (by @kazupon)') 54 | }) 55 | --------------------------------------------------------------------------------