UNPKG

@atomist/sdm-pack-changelog

Version:

Extension Pack for an Atomist SDM to manage changelogs

141 lines (111 loc) 3.82 kB
// Copied from https://github.com/hypermodules/changelog-parser // Changed so that it doesn't remove markdown formatting in list items var EOL = require('os').EOL var lineReader = require('line-reader') // patterns var semver = /\[?v?([\w\d.-]+\.[\w\d.-]+[a-zA-Z0-9])\]?/ var date = /.*[ ](\d\d?\d?\d?[-/.]\d\d?[-/.]\d\d?\d?\d?).*/ var subhead = /^###/ var listitem = /^[*-]/ function parseChangelog (file, callback) { // return a Promise if invoked without a `callback` if (!callback || typeof callback !== 'function') { return doParse(file) } // otherwise, parse log and invoke callback doParse(file).then(function (log) { callback(null, log) }) } function doParse (file) { var data = { log: { versions: [] }, current: null } // allow `handleLine` to mutate log/current data as `this`. var cb = handleLine.bind(data) return new Promise(function (resolve, reject) { lineReader.eachLine(file, cb, EOL).then(function () { // push last version into log pushCurrent(data) // clean up description data.log.description = clean(data.log.description) if (data.log.description === '') delete data.log.description resolve(data.log) }) }) } function handleLine (line) { // skip line if it's a link label if (line.match(/^\[[^[\]]*\] *?:/)) return // set title if it's there if (!this.log.title && line.match(/^# ?[^#]/)) { this.log.title = line.substring(1).trim() return } // new version found! if (line.match(/^## ?[^#]/)) { if (this.current && this.current.title) pushCurrent(this) this.current = versionFactory() if (semver.exec(line)) this.current.version = semver.exec(line)[1] this.current.title = line.substring(2).trim() if (this.current.title && date.exec(this.current.title)) this.current.date = date.exec(this.current.title)[1] return } // deal with body or description content if (this.current) { this.current.body += line + EOL // handle case where current line is a 'subhead': // - 'handleize' subhead. // - add subhead to 'parsed' data if not already present. if (subhead.exec(line)) { var key = line.replace('###', '').trim() if (!this.current.parsed[key]) { this.current.parsed[key] = [] this.current._private.activeSubhead = key } } // handle case where current line is a 'list item': if (listitem.exec(line)) { // add line to 'catch all' array this.current.parsed._.push(line) // add line to 'active subhead' if applicable (eg. 'Added', 'Changed', etc.) if (this.current._private.activeSubhead) { this.current.parsed[this.current._private.activeSubhead].push(line) } } } else { this.log.description = (this.log.description || '') + line + EOL } } function versionFactory () { return { version: null, title: null, date: null, body: '', parsed: { _: [] }, _private: { activeSubhead: null } } } function pushCurrent (data) { // remove private properties delete data.current._private data.current.body = clean(data.current.body) data.log.versions.push(data.current) } function clean (str) { if (!str) return '' // trim str = str.trim() // remove leading newlines str = str.replace(new RegExp('[' + EOL + ']*'), '') // remove trailing newlines str = str.replace(new RegExp('[' + EOL + ']*$'), '') return str } module.exports = parseChangelog