Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git log to json (git changelog nodejs)
const { exec } = require('child_process');
// Compile 'git log' command
const command = params =>
`git log --pretty=format:"
${params.join(command.format.param)}
${command.format.line}"`;
const hash = 451436388.16325235; //Math.random()*10e8;
command.format = {
line: hash.toString(36),
param: +hash.toString(36),
};
module.exports = (schema, post = (k,v) => v) =>
new Promise((resolve, reject) => {
const keys = Object.keys(schema);
const params = keys.map(key => schema[key]);
// Execute coomand and parse result
exec(command(params), (err, stdout) => {
if(err) reject(err)
else resolve(stdout.split(command.format.line)
.filter(line => line.length)
.map(line => line.split(command.format.param)
.reduce((obj, value, idx) => {
const key = keys[idx];
obj[key] = post(key, value);
return obj;
}, {})
)
);
});
});

Git log to json

The idea is to get more flexible git log structure (json)

Implemetation (./git-log-to-json.js) is quite simple: Mapping requested parameters to git log command as pretty format placeholders

In this particular case I'm going to generate changelog based on commit messages grouped by tags(versions):

#!/usr/bin/env node
const log = require('./git-log-to-json');

const tagName = /tag\:\s*v([\d|\.]*[-\.][\w]*)\,?/g;
const isTagName = str => {
  const match = tagName.exec(str);
  return match && match[1];
}

const changelog = {};

// get log info with mapped properties to log format, 
// https://git-scm.com/docs/git-log#_pretty_formats
log({ tag: "%d", note: "%N", msg: "%s"},  

  // replace \r\n etc from value
  (key, value) => value.replace(/\s\s/g,''))
    .then( records => {

      let tag = changelog['HEAD'] = [];
      records.forEach(record => {
        const tagName = isTagName(record.tag);
        if(tagName) tag = changelog[tagName] = [];
        tag.push(record.msg);
      })

      console.log(changelog);
    });

and the result (from console.log(changelog)):

{
  "HEAD":[],
  "0.0.3":[
    "Commit message #6",
    "Commit message #5",
  ],
  "0.0.2":[
    "Commit message #4",
    "Commit message #3",
  ],
  "0.0.1":[
    "Commit message #2",
    "Commit message #1",
  ]
}

As you could mention there is nodejs hashbang "#!/usr/bin/env node", and now it is possible to run changelog generation from npm scripts: "changelog":"./changelog.js"

Also, why it is important to keep changelog I would recomend to use git notes --ref=changelog/features instead of commit messages to store changelog information

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.