Skip to content

Commit

Permalink
Merge pull request #144 from CookPete/refactor-git-logic
Browse files Browse the repository at this point in the history
Refactor codebase
  • Loading branch information
cookpete authored Apr 10, 2020
2 parents bafe90c + 0aff625 commit 09890c1
Show file tree
Hide file tree
Showing 35 changed files with 938 additions and 2,287 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
node_modules
package-lock.json
yarn.lock
npm-debug.log
/lib
/coverage
1 change: 0 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
src
test
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ cache:
script:
- npm run lint
- npm run lint-markdown
- npm run test
- npm run test-coverage
after_success:
- npm run coverage
- npm run report-coverage
env:
global:
secure: F80ocIyMwaljpsWzLXRhoXTxR7kkYE0V9rTpAzO7MI/OmQ2UiAeQkyTXdthK6tZuz1oVVrpjDtYuJ0hmvlTBm7WmVWNK0S6kYhHsHGy1sRmwilBqVSwSFEcjjKmOAJckfIHwOG8tjWLY9qemrf9KqpvPCG7DiG4Pn+YHLOZT7XlXbBiec/qCnaskwBpN5KhA+VAhupcZEQAy5AWW5h+CU7NF60a4chlX4gmWjAgeHZlYr472pNRi+kDZVztaXusTEWExJog/NZ/Oi8VTZkzX0t3uNiWmLfRyYC1S8blq/jaPRuwtJrgzZZRRHZswN01cmBl/D8HAzvgrA24k/70QpNdjFeJ4s5PW9+4GiGnky5z5F3tB8Hlv0ofNQAR3IKAnI+lXy/DfSD10ZJls4bQMEdoPdG/34E5EGliG2WmP6chuTh8vPlZtOGMesUi0TkXSoYPO5njZEV0Ketye37LHTfwO4sf6OC0tV8MsTtLjqMU+081K20ACHITwaJlpfWP1uGLJn+zUx3XsGS8z7abt9+a9cPl9p917IpDttLsdtLhvGC988uWvJQ5F6UMlayf1MYavwmz0vKldDu3eHBKJSaTDqugwvivww3TxdG7Jw/mNVYsrdWz4Hr49QuugGxiOrL5ZtEIbBV50W0sPFe4XFXGFyjN2x/8/td3ZXL8glN4=
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ Options:
--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 release tags
--tag-pattern [regex] # override regex pattern for version tags
--tag-prefix [prefix] # prefix used in version tags, default: v
--starting-commit [hash] # starting commit to use for changelog generation
--starting-version [tag] # specify earliest version to include in changelog
--sort-commits [property] # sort commits by property [relevance, date, date-desc], default: relevance
--include-branch [branch] # one or more branches to include commits from, comma separated
--release-summary # display tagged commit message body as release summary
--handlebars-setup [file] # handlebars setup file
--append-git-log [string] # string to append to git log command
Expand Down Expand Up @@ -118,7 +117,7 @@ auto-changelog --compare-url https://example.com/repo/compare/{from}...{to}

#### Configuration

You can set any option in `package.json` under the `auto-changelog` key, using camelCase options. Note that `includeBranch` should be an array here, not a comma separated list:
You can set any option in `package.json` under the `auto-changelog` key, using camelCase options.

```js
{
Expand All @@ -131,11 +130,7 @@ You can set any option in `package.json` under the `auto-changelog` key, using c
"output": "HISTORY.md",
"template": "keepachangelog",
"unreleased": true,
"commitLimit": false,
"includeBranch": [
"release-v2",
"release-v3"
]
"commitLimit": false
}
}
```
Expand Down
40 changes: 13 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
"name": "auto-changelog",
"version": "1.16.4",
"description": "Command line tool for generating a changelog from git tags and commit history",
"main": "./lib/index.js",
"main": "./src/index.js",
"bin": {
"auto-changelog": "./lib/index.js"
"auto-changelog": "./src/index.js"
},
"engines": {
"node": ">=8.3"
},
"scripts": {
"lint": "standard --verbose | snazzy",
"lint-fix": "standard --fix",
"lint-markdown": "markdownlint README.md test/data/*.md",
"test": "cross-env NODE_ENV=test nyc mocha test",
"coverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json",
"clean": "rimraf lib coverage",
"build": "babel src -d lib",
"test": "cross-env NODE_ENV=test mocha -r @babel/register test",
"test-coverage": "cross-env NODE_ENV=test nyc mocha test",
"report-coverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json",
"preversion": "npm run lint && npm run test",
"version": "babel-node src/index.js --package && git add CHANGELOG.md",
"prepublishOnly": "npm run clean && npm run build",
"generate-test-data": "cross-env NODE_ENV=test babel-node scripts/generate-test-data.js"
"version": "node src/index.js --package && git add CHANGELOG.md",
"generate-test-data": "cross-env NODE_ENV=test node scripts/generate-test-data.js"
},
"author": "Pete Cook <pete@cookpete.com> (https://github.com/cookpete)",
"homepage": "https://github.com/CookPete/auto-changelog",
Expand All @@ -43,21 +44,15 @@
"license": "MIT",
"dependencies": {
"commander": "^5.0.0",
"core-js": "^3.6.4",
"handlebars": "^4.7.3",
"lodash.uniqby": "^4.7.0",
"node-fetch": "^2.6.0",
"parse-github-url": "^1.0.2",
"regenerator-runtime": "^0.13.5",
"semver": "^6.3.0"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/node": "^7.8.7",
"@babel/preset-env": "^7.9.0",
"@babel/register": "^7.9.0",
"babel-eslint": "^10.1.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-rewire": "^1.2.0",
"chai": "^4.2.0",
Expand All @@ -66,20 +61,10 @@
"markdownlint-cli": "^0.22.0",
"mocha": "^7.1.1",
"nyc": "^15.0.0",
"rimraf": "^3.0.2",
"snazzy": "^8.0.0",
"standard": "^14.3.3"
},
"babel": {
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"env": {
"test": {
"plugins": [
Expand All @@ -90,7 +75,6 @@
}
},
"standard": {
"parser": "babel-eslint",
"ignore": [
"test/data/"
]
Expand All @@ -104,12 +88,14 @@
"report-dir": "./coverage",
"temp-dir": "./coverage/.nyc_output",
"require": [
"core-js/stable",
"@babel/register"
],
"reporter": [
"text",
"html"
]
},
"auto-changelog": {
"breakingPattern": "Breaking change"
}
}
14 changes: 7 additions & 7 deletions scripts/generate-test-data.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { join } from 'path'
import { readFile, writeFile } from '../src/utils'
import { __get__ } from '../src/commits'
import { parseReleases } from '../src/releases'
import { compileTemplate } from '../src/template'
import remotes from '../test/data/remotes'
const { join } = require('path')
const { readFile, writeFile } = require('../src/utils')
const { __get__ } = require('../src/commits')
const { parseReleases } = require('../src/releases')
const { compileTemplate } = require('../src/template')
const remotes = require('../test/data/remotes')

const parseCommits = __get__('parseCommits')

Expand All @@ -17,7 +17,7 @@ const options = {
}

function writeObject (filename, object) {
return writeFile(join(DATA_DIR, filename), `export default ${JSON.stringify(object, null, 2)}\n`)
return writeFile(join(DATA_DIR, filename), `module.exports = ${JSON.stringify(object, null, 2)}\n`)
}

async function writeTemplate (filename, template, releases) {
Expand Down
65 changes: 20 additions & 45 deletions src/commits.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import semver from 'semver'
import { cmd, isLink, encodeHTML, replaceText, getGitVersion } from './utils'
const semver = require('semver')
const { cmd, isLink, encodeHTML, replaceText, getGitVersion } = require('./utils')

const COMMIT_SEPARATOR = '__AUTO_CHANGELOG_COMMIT_SEPARATOR__'
const MESSAGE_SEPARATOR = '__AUTO_CHANGELOG_MESSAGE_SEPARATOR__'
const MATCH_COMMIT = /(.*)\n(?:\s\((.*)\))?\n(.*)\n(.*)\n(.*)\n([\S\s]+)/
const MATCH_COMMIT = /(.*)\n(.*)\n(.*)\n(.*)\n([\S\s]+)/
const MATCH_STATS = /(\d+) files? changed(?:, (\d+) insertions?...)?(?:, (\d+) deletions?...)?/
const BODY_FORMAT = '%B'
const FALLBACK_BODY_FORMAT = '%s%n%n%b'
Expand All @@ -12,44 +12,33 @@ const FALLBACK_BODY_FORMAT = '%s%n%n%b'
const DEFAULT_FIX_PATTERN = /(?:close[sd]?|fixe?[sd]?|resolve[sd]?)\s(?:#(\d+)|(https?:\/\/.+?\/(?:issues|pull|pull-requests|merge_requests)\/(\d+)))/gi

const MERGE_PATTERNS = [
/Merge pull request #(\d+) from .+\n\n(.+)/, // Regular GitHub merge
/^Merge pull request #(\d+) from .+\n\n(.+)/, // Regular GitHub merge
/^(.+) \(#(\d+)\)(?:$|\n\n)/, // Github squash merge
/Merged in .+ \(pull request #(\d+)\)\n\n(.+)/, // BitBucket merge
/Merge branch .+ into .+\n\n(.+)[\S\s]+See merge request [^!]*!(\d+)/ // GitLab merge
/^Merged in .+ \(pull request #(\d+)\)\n\n(.+)/, // BitBucket merge
/^Merge branch .+ into .+\n\n(.+)[\S\s]+See merge request [^!]*!(\d+)/ // GitLab merge
]

export async function fetchCommits (remote, options, branch = null, onProgress) {
const command = branch ? `git log ${branch}` : 'git log'
async function fetchCommits (diff, remote, options = {}) {
const format = await getLogFormat()
const log = await cmd(`${command} --shortstat --pretty=format:${format} ${options.appendGitLog}`, onProgress)
const log = await cmd(`git log ${diff} --shortstat --pretty=format:${format} ${options.appendGitLog}`)
return parseCommits(log, remote, options)
}

async function getLogFormat () {
const gitVersion = await getGitVersion()
const bodyFormat = gitVersion && semver.gte(gitVersion, '1.7.2') ? BODY_FORMAT : FALLBACK_BODY_FORMAT
return `${COMMIT_SEPARATOR}%H%n%d%n%ai%n%an%n%ae%n${bodyFormat}${MESSAGE_SEPARATOR}`
return `${COMMIT_SEPARATOR}%H%n%ai%n%an%n%ae%n${bodyFormat}${MESSAGE_SEPARATOR}`
}

function parseCommits (string, remote, options = {}) {
const commits = string
return string
.split(COMMIT_SEPARATOR)
.slice(1)
.map(commit => parseCommit(commit, remote, options))

if (options.startingCommit) {
const index = commits.findIndex(c => c.hash.indexOf(options.startingCommit) === 0)
if (index === -1) {
throw new Error(`Starting commit ${options.startingCommit} was not found`)
}
return commits.slice(0, index + 1)
}

return commits
}

function parseCommit (commit, remote, options = {}) {
const [, hash, refs, date, author, email, tail] = commit.match(MATCH_COMMIT)
const [, hash, date, author, email, tail] = commit.match(MATCH_COMMIT)
const [body, stats] = tail.split(MESSAGE_SEPARATOR)
const message = encodeHTML(body)
const parsed = {
Expand All @@ -58,40 +47,19 @@ function parseCommit (commit, remote, options = {}) {
author,
email,
date: new Date(date).toISOString(),
tag: getTag(refs, options),
subject: replaceText(getSubject(message), options),
message: message.trim(),
fixes: getFixes(message, author, remote, options),
href: remote.getCommitLink(hash),
breaking: !!options.breakingPattern && new RegExp(options.breakingPattern).test(message),
...getStats(stats.trim())
...getStats(stats)
}
return {
...parsed,
merge: getMerge(parsed, message, remote, options)
}
}

function getTag (refs, options) {
if (!refs) return null
for (const ref of refs.split(', ')) {
const prefix = `tag: ${options.tagPrefix}`
if (ref.indexOf(prefix) === 0) {
const tag = ref.replace(prefix, '')
if (options.tagPattern) {
if (new RegExp(options.tagPattern).test(tag)) {
return tag
}
return null
}
if (semver.valid(tag)) {
return tag
}
}
}
return null
}

function getSubject (message) {
if (!message) {
return '_No commit message_'
Expand All @@ -100,7 +68,7 @@ function getSubject (message) {
}

function getStats (stats) {
if (!stats) return {}
if (!stats.trim()) return {}
const [, files, insertions, deletions] = stats.match(MATCH_STATS)
return {
files: parseInt(files || 0),
Expand Down Expand Up @@ -164,3 +132,10 @@ function getMerge (commit, message, remote, options = {}) {
}
return null
}

module.exports = {
COMMIT_SEPARATOR,
MESSAGE_SEPARATOR,
fetchCommits,
parseCommit
}
14 changes: 6 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env node

import 'core-js/stable'
import run from './run'
const { run } = require('./run')

run(process.argv)
.catch(error => {
console.log('\n')
console.error(error)
process.exit(1)
})
run(process.argv).catch(error => {
console.log('\n')
console.error(error)
process.exit(1)
})
Loading

0 comments on commit 09890c1

Please sign in to comment.