conventional-commits-parser 3.1.0 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.2.0](https://github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser@3.1.0...conventional-commits-parser@3.2.0) (2020-11-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * ignore gpg lines ([#685](https://github.com/conventional-changelog/conventional-changelog/issues/685)) ([f8fcbc2](https://github.com/conventional-changelog/conventional-changelog/commit/f8fcbc2e8b0834c29178ace6382b438a020ad828))
12
+ * **deps:** update dependency through2 to v4 ([#657](https://github.com/conventional-changelog/conventional-changelog/issues/657)) ([7ae618c](https://github.com/conventional-changelog/conventional-changelog/commit/7ae618c81491841e5b1d796d3933aac0c54bc312))
13
+
14
+
15
+ ### Features
16
+
17
+ * allows notes pattern to be customized ([#586](https://github.com/conventional-changelog/conventional-changelog/issues/586)) ([9c00f32](https://github.com/conventional-changelog/conventional-changelog/commit/9c00f3242d916be1774a618d943f908f8d9699a6))
18
+
19
+
20
+
21
+
22
+
6
23
  # [3.1.0](https://github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser@3.0.8...conventional-commits-parser@3.1.0) (2020-05-08)
7
24
 
8
25
 
@@ -20,6 +37,27 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
20
37
 
21
38
 
22
39
 
40
+ ### [3.2.3](https://www.github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser-v3.2.2...conventional-commits-parser-v3.2.3) (2021-10-23)
41
+
42
+
43
+ ### Bug Fixes
44
+
45
+ * address ReDoS issue ([#861](https://www.github.com/conventional-changelog/conventional-changelog/issues/861)) ([c696fa3](https://www.github.com/conventional-changelog/conventional-changelog/commit/c696fa35f93e0ee13728d6cf1221587ac6386311))
46
+
47
+ ### [3.2.2](https://www.github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser-v3.2.1...conventional-commits-parser-v3.2.2) (2021-09-09)
48
+
49
+
50
+ ### Bug Fixes
51
+
52
+ * **conventional-commits-parser:** address CVE-2021-23425 ([#841](https://www.github.com/conventional-changelog/conventional-changelog/issues/841)) ([02b3d53](https://www.github.com/conventional-changelog/conventional-changelog/commit/02b3d53a0c142f0c28ee7d190d210c76a62887c2))
53
+
54
+ ### [3.2.1](https://www.github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser@3.2.0...v3.2.1) (2021-02-15)
55
+
56
+
57
+ ### Bug Fixes
58
+
59
+ * handle missing header in merge commit ([#757](https://www.github.com/conventional-changelog/conventional-changelog/issues/757)) ([d189d3e](https://www.github.com/conventional-changelog/conventional-changelog/commit/d189d3e45b82e7141115ce8eccd95c8cf2d7db77))
60
+
23
61
  ## [3.0.8](https://github.com/conventional-changelog/conventional-changelog/compare/conventional-commits-parser@3.0.7...conventional-commits-parser@3.0.8) (2019-11-14)
24
62
 
25
63
 
package/README.md CHANGED
@@ -205,6 +205,12 @@ Type: `array` of `string` or `string` Default: `['BREAKING CHANGE']`
205
205
 
206
206
  Keywords for important notes. This value is case **insensitive**. If it's a `string` it will be converted to an `array` separated by a comma.
207
207
 
208
+ ##### notesPattern
209
+
210
+ Type: `function` Default: `noteKeywordsSelection => ^[\\s|*]*(' + noteKeywordsSelection + ')[:\\s]+(.*)` where `noteKeywordsSelection` is `join(noteKeywords, '|')`
211
+
212
+ A function that takes `noteKeywordsSelection` and returns a `RegExp` to be matched against the notes.
213
+
208
214
  ##### fieldPattern
209
215
 
210
216
  Type: `regex` or `string` Default: `/^-(.*?)-$/`
package/cli.js CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict'
3
- var conventionalCommitsParser = require('./')
4
- var forEach = require('lodash').forEach
5
- var fs = require('fs')
6
- var isTextPath = require('is-text-path')
7
- var JSONStream = require('JSONStream')
8
- var meow = require('meow')
9
- var readline = require('readline')
10
- var split = require('split2')
11
- var through = require('through2')
3
+ const conventionalCommitsParser = require('./')
4
+ const forEach = require('lodash').forEach
5
+ const fs = require('fs')
6
+ const isTextPath = require('is-text-path')
7
+ const JSONStream = require('JSONStream')
8
+ const meow = require('meow')
9
+ const readline = require('readline')
10
+ const split = require('split2')
11
+ const through = require('through2')
12
12
 
13
- var filePaths = []
14
- var separator = '\n\n\n'
13
+ const filePaths = []
14
+ let separator = '\n\n\n'
15
15
 
16
- var cli = meow(`
16
+ const cli = meow(`
17
17
  Practice writing commit messages or parse messages from files.
18
18
  If used without specifying a text file path, you will enter an interactive shell.
19
19
  Otherwise the commit messages in the files are parsed and printed
@@ -91,15 +91,15 @@ forEach(cli.input, function (arg) {
91
91
  }
92
92
  })
93
93
 
94
- var length = filePaths.length
95
- var options = cli.flags
94
+ const length = filePaths.length
95
+ const options = cli.flags
96
96
 
97
97
  if (options.verbose) {
98
98
  options.warn = console.log.bind(console)
99
99
  }
100
100
 
101
101
  function processFile (fileIndex) {
102
- var filePath = filePaths[fileIndex]
102
+ const filePath = filePaths[fileIndex]
103
103
  fs.createReadStream(filePath)
104
104
  .on('error', function (err) {
105
105
  console.warn('Failed to read file ' + filePath + '\n' + err)
@@ -122,9 +122,9 @@ if (process.stdin.isTTY) {
122
122
  if (length > 0) {
123
123
  processFile(0)
124
124
  } else {
125
- var commit = ''
126
- var stream = through()
127
- var rl = readline.createInterface({
125
+ let commit = ''
126
+ const stream = through()
127
+ const rl = readline.createInterface({
128
128
  input: process.stdin,
129
129
  output: process.stdout,
130
130
  terminal: true
package/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
- var parser = require('./lib/parser')
4
- var regex = require('./lib/regex')
5
- var through = require('through2')
6
- var _ = require('lodash')
3
+ const parser = require('./lib/parser')
4
+ const regex = require('./lib/regex')
5
+ const through = require('through2')
6
+ const _ = require('lodash')
7
7
 
8
8
  function assignOpts (options) {
9
9
  options = _.extend({
@@ -71,10 +71,10 @@ function assignOpts (options) {
71
71
 
72
72
  function conventionalCommitsParser (options) {
73
73
  options = assignOpts(options)
74
- var reg = regex(options)
74
+ const reg = regex(options)
75
75
 
76
76
  return through.obj(function (data, enc, cb) {
77
- var commit
77
+ let commit
78
78
 
79
79
  try {
80
80
  commit = parser(data.toString(), options, reg)
@@ -92,7 +92,7 @@ function conventionalCommitsParser (options) {
92
92
 
93
93
  function sync (commit, options) {
94
94
  options = assignOpts(options)
95
- var reg = regex(options)
95
+ const reg = regex(options)
96
96
 
97
97
  return parser(commit, options, reg)
98
98
  }
package/lib/parser.js CHANGED
@@ -1,9 +1,21 @@
1
1
  'use strict'
2
- var trimOffNewlines = require('trim-off-newlines')
3
- var _ = require('lodash')
2
+ const _ = require('lodash')
4
3
 
5
- var CATCH_ALL = /()(.+)/gi
6
- var SCISSOR = '# ------------------------ >8 ------------------------'
4
+ const CATCH_ALL = /()(.+)/gi
5
+ const SCISSOR = '# ------------------------ >8 ------------------------'
6
+
7
+ function trimOffNewlines (input) {
8
+ const result = input.match(/[^\r\n]/)
9
+ if (!result) {
10
+ return ''
11
+ }
12
+ const firstIndex = result.index
13
+ let lastIndex = input.length - 1
14
+ while (input[lastIndex] === '\r' || input[lastIndex] === '\n') {
15
+ lastIndex--
16
+ }
17
+ return input.substring(firstIndex, lastIndex + 1)
18
+ }
7
19
 
8
20
  function append (src, line) {
9
21
  if (src) {
@@ -22,7 +34,7 @@ function getCommentFilter (char) {
22
34
  }
23
35
 
24
36
  function truncateToScissor (lines) {
25
- var scissorIndex = lines.indexOf(SCISSOR)
37
+ const scissorIndex = lines.indexOf(SCISSOR)
26
38
 
27
39
  if (scissorIndex === -1) {
28
40
  return lines
@@ -32,29 +44,29 @@ function truncateToScissor (lines) {
32
44
  }
33
45
 
34
46
  function getReferences (input, regex) {
35
- var references = []
36
- var referenceSentences
37
- var referenceMatch
47
+ const references = []
48
+ let referenceSentences
49
+ let referenceMatch
38
50
 
39
- var reApplicable = input.match(regex.references) !== null
51
+ const reApplicable = input.match(regex.references) !== null
40
52
  ? regex.references
41
53
  : CATCH_ALL
42
54
 
43
55
  while ((referenceSentences = reApplicable.exec(input))) {
44
- var action = referenceSentences[1] || null
45
- var sentence = referenceSentences[2]
56
+ const action = referenceSentences[1] || null
57
+ const sentence = referenceSentences[2]
46
58
 
47
59
  while ((referenceMatch = regex.referenceParts.exec(sentence))) {
48
- var owner = null
49
- var repository = referenceMatch[1] || ''
50
- var ownerRepo = repository.split('/')
60
+ let owner = null
61
+ let repository = referenceMatch[1] || ''
62
+ const ownerRepo = repository.split('/')
51
63
 
52
64
  if (ownerRepo.length > 1) {
53
65
  owner = ownerRepo.shift()
54
66
  repository = ownerRepo.join('/')
55
67
  }
56
68
 
57
- var reference = {
69
+ const reference = {
58
70
  action: action,
59
71
  owner: owner,
60
72
  repository: repository || null,
@@ -87,39 +99,37 @@ function parser (raw, options, regex) {
87
99
  throw new TypeError('Expected regex')
88
100
  }
89
101
 
90
- var headerMatch
91
- var mergeMatch
92
- var currentProcessedField
93
- var mentionsMatch
94
- var revertMatch
95
- var otherFields = {}
96
- var commentFilter = typeof options.commentChar === 'string'
102
+ let currentProcessedField
103
+ let mentionsMatch
104
+ const otherFields = {}
105
+ const commentFilter = typeof options.commentChar === 'string'
97
106
  ? getCommentFilter(options.commentChar)
98
107
  : passTrough
108
+ const gpgFilter = line => !line.match(/^\s*gpg:/)
99
109
 
100
- var rawLines = trimOffNewlines(raw).split(/\r?\n/)
101
- var lines = truncateToScissor(rawLines).filter(commentFilter)
110
+ const rawLines = trimOffNewlines(raw).split(/\r?\n/)
111
+ const lines = truncateToScissor(rawLines).filter(commentFilter).filter(gpgFilter)
102
112
 
103
- var continueNote = false
104
- var isBody = true
105
- var headerCorrespondence = _.map(options.headerCorrespondence, function (part) {
113
+ let continueNote = false
114
+ let isBody = true
115
+ const headerCorrespondence = _.map(options.headerCorrespondence, function (part) {
106
116
  return part.trim()
107
117
  })
108
- var revertCorrespondence = _.map(options.revertCorrespondence, function (field) {
118
+ const revertCorrespondence = _.map(options.revertCorrespondence, function (field) {
109
119
  return field.trim()
110
120
  })
111
- var mergeCorrespondence = _.map(options.mergeCorrespondence, function (field) {
121
+ const mergeCorrespondence = _.map(options.mergeCorrespondence, function (field) {
112
122
  return field.trim()
113
123
  })
114
124
 
115
- var body = null
116
- var footer = null
117
- var header = null
118
- var mentions = []
119
- var merge = null
120
- var notes = []
121
- var references = []
122
- var revert = null
125
+ let body = null
126
+ let footer = null
127
+ let header = null
128
+ const mentions = []
129
+ let merge = null
130
+ const notes = []
131
+ const references = []
132
+ let revert = null
123
133
 
124
134
  if (lines.length === 0) {
125
135
  return {
@@ -139,22 +149,25 @@ function parser (raw, options, regex) {
139
149
 
140
150
  // msg parts
141
151
  merge = lines.shift()
142
- var mergeParts = {}
143
- var headerParts = {}
152
+ const mergeParts = {}
153
+ const headerParts = {}
144
154
  body = ''
145
155
  footer = ''
146
156
 
147
- mergeMatch = merge.match(options.mergePattern)
157
+ const mergeMatch = merge.match(options.mergePattern)
148
158
  if (mergeMatch && options.mergePattern) {
149
159
  merge = mergeMatch[0]
150
160
 
151
161
  header = lines.shift()
152
- while (!header.trim()) {
162
+ while (header !== undefined && !header.trim()) {
153
163
  header = lines.shift()
154
164
  }
165
+ if (!header) {
166
+ header = ''
167
+ }
155
168
 
156
169
  _.forEach(mergeCorrespondence, function (partName, index) {
157
- var partValue = mergeMatch[index + 1] || null
170
+ const partValue = mergeMatch[index + 1] || null
158
171
  mergeParts[partName] = partValue
159
172
  })
160
173
  } else {
@@ -166,10 +179,10 @@ function parser (raw, options, regex) {
166
179
  })
167
180
  }
168
181
 
169
- headerMatch = header.match(options.headerPattern)
182
+ const headerMatch = header.match(options.headerPattern)
170
183
  if (headerMatch) {
171
184
  _.forEach(headerCorrespondence, function (partName, index) {
172
- var partValue = headerMatch[index + 1] || null
185
+ const partValue = headerMatch[index + 1] || null
173
186
  headerParts[partName] = partValue
174
187
  })
175
188
  } else {
@@ -186,7 +199,7 @@ function parser (raw, options, regex) {
186
199
  // body or footer
187
200
  _.forEach(lines, function (line) {
188
201
  if (options.fieldPattern) {
189
- var fieldMatch = options.fieldPattern.exec(line)
202
+ const fieldMatch = options.fieldPattern.exec(line)
190
203
 
191
204
  if (fieldMatch) {
192
205
  currentProcessedField = fieldMatch[1]
@@ -201,16 +214,16 @@ function parser (raw, options, regex) {
201
214
  }
202
215
  }
203
216
 
204
- var referenceMatched
217
+ let referenceMatched
205
218
 
206
219
  // this is a new important note
207
- var notesMatch = line.match(regex.notes)
220
+ const notesMatch = line.match(regex.notes)
208
221
  if (notesMatch) {
209
222
  continueNote = true
210
223
  isBody = false
211
224
  footer = append(footer, line)
212
225
 
213
- var note = {
226
+ const note = {
214
227
  title: notesMatch[1],
215
228
  text: notesMatch[2]
216
229
  }
@@ -220,7 +233,7 @@ function parser (raw, options, regex) {
220
233
  return
221
234
  }
222
235
 
223
- var lineReferences = getReferences(line, {
236
+ const lineReferences = getReferences(line, {
224
237
  references: regex.references,
225
238
  referenceParts: regex.referenceParts
226
239
  })
@@ -254,7 +267,7 @@ function parser (raw, options, regex) {
254
267
  })
255
268
 
256
269
  if (options.breakingHeaderPattern && notes.length === 0) {
257
- var breakingHeader = header.match(options.breakingHeaderPattern)
270
+ const breakingHeader = header.match(options.breakingHeaderPattern)
258
271
  if (breakingHeader) {
259
272
  const noteText = breakingHeader[3] // the description of the change.
260
273
  notes.push({
@@ -269,11 +282,11 @@ function parser (raw, options, regex) {
269
282
  }
270
283
 
271
284
  // does this commit revert any other commit?
272
- revertMatch = raw.match(options.revertPattern)
285
+ const revertMatch = raw.match(options.revertPattern)
273
286
  if (revertMatch) {
274
287
  revert = {}
275
288
  _.forEach(revertCorrespondence, function (partName, index) {
276
- var partValue = revertMatch[index + 1] || null
289
+ const partValue = revertMatch[index + 1] || null
277
290
  revert[partName] = partValue
278
291
  })
279
292
  } else {
@@ -286,7 +299,7 @@ function parser (raw, options, regex) {
286
299
  return note
287
300
  })
288
301
 
289
- var msg = _.merge(headerParts, mergeParts, {
302
+ const msg = _.merge(headerParts, mergeParts, {
290
303
  merge: merge,
291
304
  header: header,
292
305
  body: body ? trimOffNewlines(body) : null,
package/lib/regex.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- var reNomatch = /(?!.*)/
3
+ const reNomatch = /(?!.*)/
4
4
 
5
5
  function join (array, joiner) {
6
6
  return array
@@ -13,12 +13,18 @@ function join (array, joiner) {
13
13
  .join(joiner)
14
14
  }
15
15
 
16
- function getNotesRegex (noteKeywords) {
16
+ function getNotesRegex (noteKeywords, notesPattern) {
17
17
  if (!noteKeywords) {
18
18
  return reNomatch
19
19
  }
20
20
 
21
- return new RegExp('^[\\s|*]*(' + join(noteKeywords, '|') + ')[:\\s]+(.*)', 'i')
21
+ const noteKeywordsSelection = join(noteKeywords, '|')
22
+
23
+ if (!notesPattern) {
24
+ return new RegExp('^[\\s|*]*(' + noteKeywordsSelection + ')[:\\s]+(.*)', 'i')
25
+ }
26
+
27
+ return notesPattern(noteKeywordsSelection)
22
28
  }
23
29
 
24
30
  function getReferencePartsRegex (issuePrefixes, issuePrefixesCaseSensitive) {
@@ -26,7 +32,7 @@ function getReferencePartsRegex (issuePrefixes, issuePrefixesCaseSensitive) {
26
32
  return reNomatch
27
33
  }
28
34
 
29
- var flags = issuePrefixesCaseSensitive ? 'g' : 'gi'
35
+ const flags = issuePrefixesCaseSensitive ? 'g' : 'gi'
30
36
  return new RegExp('(?:.*?)??\\s*([\\w-\\.\\/]*?)??(' + join(issuePrefixes, '|') + ')([\\w-]*\\d+)', flags)
31
37
  }
32
38
 
@@ -36,15 +42,15 @@ function getReferencesRegex (referenceActions) {
36
42
  return /()(.+)/gi
37
43
  }
38
44
 
39
- var joinedKeywords = join(referenceActions, '|')
45
+ const joinedKeywords = join(referenceActions, '|')
40
46
  return new RegExp('(' + joinedKeywords + ')(?:\\s+(.*?))(?=(?:' + joinedKeywords + ')|$)', 'gi')
41
47
  }
42
48
 
43
49
  module.exports = function (options) {
44
50
  options = options || {}
45
- var reNotes = getNotesRegex(options.noteKeywords)
46
- var reReferenceParts = getReferencePartsRegex(options.issuePrefixes, options.issuePrefixesCaseSensitive)
47
- var reReferences = getReferencesRegex(options.referenceActions)
51
+ const reNotes = getNotesRegex(options.noteKeywords, options.notesPattern)
52
+ const reReferenceParts = getReferencePartsRegex(options.issuePrefixes, options.issuePrefixesCaseSensitive)
53
+ const reReferences = getReferencesRegex(options.referenceActions)
48
54
 
49
55
  return {
50
56
  notes: reNotes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conventional-commits-parser",
3
- "version": "3.1.0",
3
+ "version": "3.2.3",
4
4
  "description": "Parse raw conventional commits",
5
5
  "bugs": {
6
6
  "url": "https://github.com/conventional-changelog/conventional-changelog/issues"
@@ -33,13 +33,12 @@
33
33
  "logs"
34
34
  ],
35
35
  "dependencies": {
36
- "JSONStream": "^1.0.4",
37
36
  "is-text-path": "^1.0.1",
37
+ "JSONStream": "^1.0.4",
38
38
  "lodash": "^4.17.15",
39
- "meow": "^7.0.0",
40
- "split2": "^2.0.0",
41
- "through2": "^3.0.0",
42
- "trim-off-newlines": "^1.0.0"
39
+ "meow": "^8.0.0",
40
+ "split2": "^3.0.0",
41
+ "through2": "^4.0.0"
43
42
  },
44
43
  "scripts": {
45
44
  "test-windows": "echo 'make work on windows'"
@@ -49,6 +48,5 @@
49
48
  },
50
49
  "devDependencies": {
51
50
  "forceable-tty": "^0.1.0"
52
- },
53
- "gitHead": "83643c5a0d2c4d7c9ba14cbf990ffbc577a51e8c"
51
+ }
54
52
  }