From 6d9fb9a46258a8e8f42cddee05ef145908b690b3 Mon Sep 17 00:00:00 2001 From: Rafael Gonzaga Date: Tue, 18 Feb 2025 23:19:18 -0300 Subject: [PATCH] feat: split commit-to-list to its own file (#178) Split commitToList to its own file will allow libraries to create their own custom format --- changelog-maker.js | 90 +++++++--------------------------------------- commit-to-list.js | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 78 deletions(-) create mode 100644 commit-to-list.js diff --git a/changelog-maker.js b/changelog-maker.js index ad1f1f3..ea2af2c 100755 --- a/changelog-maker.js +++ b/changelog-maker.js @@ -1,23 +1,19 @@ #!/usr/bin/env node -import { existsSync, readFileSync } from 'fs' -import { join } from 'path' -import process from 'process' -import { pipeline as _pipeline } from 'stream' -import { promisify } from 'util' -import split2 from 'split2' -import pkgtoId from 'pkg-to-id' -import commitStream from 'commit-stream' -import gitexec from 'gitexec' import _debug from 'debug' +import process from 'process' import minimist from 'minimist' +import pkgtoId from 'pkg-to-id' +import { existsSync, readFileSync } from 'fs' +import { join } from 'path' import { processCommits } from './process-commits.js' -import { isReleaseCommit } from './groups.js' +import { commitToList } from './commit-to-list.js' -const pipeline = promisify(_pipeline) const debug = _debug('changelog-maker') + const argv = minimist(process.argv.slice(2)) const help = argv.h || argv.help + const pkgFile = join(process.cwd(), 'package.json') const pkgData = existsSync(pkgFile) ? JSON.parse(readFileSync(pkgFile)) : {} const pkgId = pkgtoId(pkgData) @@ -26,15 +22,6 @@ const ghId = { user: argv._[0] || pkgId.user || 'nodejs', repo: argv._[1] || (pkgId.name && stripScope(pkgId.name)) || 'node' } - -const gitcmd = 'git log --pretty=full --since="{{sincecmd}}" --until="{{untilcmd}}"' -const commitdatecmd = '$(git show -s --format=%cd `{{refcmd}}`)' -const untilcmd = '' -const refcmd = argv.a || argv.all ? 'git rev-list --max-parents=0 HEAD' : 'git rev-list --max-count=1 {{ref}}' -const defaultRef = '--tags=v*.*.* 2> /dev/null ' + - '|| git rev-list --max-count=1 --tags=*.*.* 2> /dev/null ' + - '|| git rev-list --max-count=1 HEAD' - debug(ghId) if (help) { @@ -42,6 +29,10 @@ if (help) { process.exit(0) } +function stripScope (name) { + return name[0] === '@' && name.indexOf('/') > 0 ? name.split('/')[1] : name +} + function showUsage () { const usage = readFileSync(new URL('README.md', import.meta.url), 'utf8') .replace(/[\s\S]+(## Usage\n[\s\S]*)\n## [\s\S]+/m, '$1') @@ -52,65 +43,8 @@ function showUsage () { process.stdout.write(usage) } -function stripScope (name) { - return name[0] === '@' && name.indexOf('/') > 0 ? name.split('/')[1] : name -} - -function replace (s, m) { - Object.keys(m).forEach((k) => { - s = s.replace(new RegExp(`\\{\\{${k}\\}\\}`, 'g'), m[k]) - }) - return s -} - -const _startrefcmd = replace(refcmd, { ref: argv['start-ref'] || defaultRef }) -const _endrefcmd = argv['end-ref'] && replace(refcmd, { ref: argv['end-ref'] }) -const _sincecmd = replace(commitdatecmd, { refcmd: _startrefcmd }) -const _untilcmd = argv['end-ref'] ? replace(commitdatecmd, { refcmd: _endrefcmd }) : untilcmd -const _gitcmd = replace(gitcmd, { sincecmd: _sincecmd, untilcmd: _untilcmd }) - -debug('%s', _startrefcmd) -debug('%s', _endrefcmd) -debug('%s', _sincecmd) -debug('%s', _untilcmd) -debug('%s', _gitcmd) - -function organiseCommits (list) { - if (argv['start-ref'] || argv.a || argv.all) { - if (argv['filter-release']) { - list = list.filter((commit) => !isReleaseCommit(commit.summary)) - } - - return list - } - - // filter commits to those _before_ 'working on ...' - let started = false - return list.filter((commit) => { - if (started) { - return false - } - - if (isReleaseCommit(commit.summary)) { - started = true - } - - return !started - }) -} - async function run () { - let commitList = [] - await pipeline( - gitexec.exec(process.cwd(), _gitcmd), - split2(), - commitStream(ghId.user, ghId.repo), - async function * (source) { - for await (const commit of source) { - commitList.push(commit) - } - }) - commitList = organiseCommits(commitList) + const commitList = await commitToList(ghId, argv) await processCommits(argv, ghId, commitList) } diff --git a/commit-to-list.js b/commit-to-list.js new file mode 100644 index 0000000..139cf04 --- /dev/null +++ b/commit-to-list.js @@ -0,0 +1,76 @@ +import _debug from 'debug' +import process from 'process' +import { pipeline as _pipeline } from 'stream' +import { promisify } from 'util' +import commitStream from 'commit-stream' +import gitexec from 'gitexec' +import split2 from 'split2' +import { isReleaseCommit } from './groups.js' + +const debug = _debug('changelog-maker') + +const pipeline = promisify(_pipeline) +const gitcmd = 'git log --pretty=full --since="{{sincecmd}}" --until="{{untilcmd}}"' +const commitdatecmd = '$(git show -s --format=%cd `{{refcmd}}`)' +const untilcmd = '' +const defaultRef = '--tags=v*.*.* 2> /dev/null ' + + '|| git rev-list --max-count=1 --tags=*.*.* 2> /dev/null ' + + '|| git rev-list --max-count=1 HEAD' + +function replace (s, m) { + Object.keys(m).forEach((k) => { + s = s.replace(new RegExp(`\\{\\{${k}\\}\\}`, 'g'), m[k]) + }) + return s +} + +function organiseCommits (argv, list) { + if (argv['start-ref'] || argv.a || argv.all) { + if (argv['filter-release']) { + list = list.filter((commit) => !isReleaseCommit(commit.summary)) + } + + return list + } + + // filter commits to those _before_ 'working on ...' + let started = false + return list.filter((commit) => { + if (started) { + return false + } + + if (isReleaseCommit(commit.summary)) { + started = true + } + + return !started + }) +} + +export async function commitToList (ghId, argv) { + const refcmd = argv.a || argv.all ? 'git rev-list --max-parents=0 HEAD' : 'git rev-list --max-count=1 {{ref}}' + const _startrefcmd = replace(refcmd, { ref: argv['start-ref'] || defaultRef }) + const _endrefcmd = argv['end-ref'] && replace(refcmd, { ref: argv['end-ref'] }) + const _sincecmd = replace(commitdatecmd, { refcmd: _startrefcmd }) + const _untilcmd = argv['end-ref'] ? replace(commitdatecmd, { refcmd: _endrefcmd }) : untilcmd + const _gitcmd = replace(gitcmd, { sincecmd: _sincecmd, untilcmd: _untilcmd }) + debug('%s', _startrefcmd) + debug('%s', _endrefcmd) + debug('%s', _sincecmd) + debug('%s', _untilcmd) + debug('%s', _gitcmd) + + let commitList = [] + await pipeline( + gitexec.exec(process.cwd(), _gitcmd), + split2(), + commitStream(ghId.user, ghId.repo), + async function * (source) { + for await (const commit of source) { + commitList.push(commit) + } + }) + commitList = organiseCommits(argv, commitList) + return commitList +}