Skip to content

Commit

Permalink
Simplifies & refactors the way git log fields are parsed
Browse files Browse the repository at this point in the history
`--pretty=tformat` string is generated automatically from array of `git log` fields.
Each field is separated by a null character, which as far as I know can't appear naturally in any of those fields.
Babel now transpiles from .es to .js, which is easier than transpiling to .compiled.js now that there are multiple .es scripts
  • Loading branch information
cspotcode committed Dec 1, 2016
1 parent 0656ce1 commit 3cfdf91
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 244 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
presets: ['es2015']
presets: ['es2015'],
only: 'scripts/**.es'
}
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ npm-debug.log
node_modules/
assets/
gitlogg.json
*.compiled.js
*.compiled.js.map
scripts/**/*.js
scripts/**/*.js.map
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
"gitlogg": "gitlogg/gitlogg.sh"
},
"scripts": {
"build": "babel --source-maps --out-file scripts/gitlogg-parse-json.compiled.js scripts/gitlogg-parse-json.js",
"build": "babel --source-maps --out-dir scripts scripts",
"test": "GITLOGG_DEV=1 ./gitlogg/gitlogg.sh ./",
"prepublish": "npm run build"
},
"dependencies": {
"chalk": "^1.1.3",
"lodash": "^4.17.2"
"lodash": "^4.17.2",
"which": "^1.2.12"
},
"devDependencies": {
"babel-cli": "^6.18.0",
Expand Down
129 changes: 67 additions & 62 deletions scripts/git-log-fields.js → scripts/git-log-fields.es
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

exports.fields = [ { code: '%H',

const fields = exports.fields = [
{ code: '%H',
name: 'commit hash',
fullDescription: 'commit hash',
description: '',
Expand Down Expand Up @@ -38,7 +39,7 @@ exports.fields = [ { code: '%H',
name: 'author name',
fullDescription: 'author name (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'author_name_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
identifier: 'author_name_mailmap' },
{ code: '%ae',
name: 'author email',
fullDescription: 'author email',
Expand All @@ -48,37 +49,37 @@ exports.fields = [ { code: '%H',
name: 'author email',
fullDescription: 'author email (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'author_email_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
{ code: '%ad',
name: 'author date',
fullDescription: 'author date (format respects --date= option)',
description: ' (format respects --date= option)',
identifier: 'author_date_(format_respects_--date=_option)' },
{ code: '%aD',
name: 'author date',
fullDescription: 'author date, RFC2822 style',
description: ', RFC2822 style',
identifier: 'author_date_RFC2822_style' },
identifier: 'author_email_mailmap' },
// { code: '%ad',
// name: 'author date',
// fullDescription: 'author date (format respects --date= option)',
// description: ' (format respects --date= option)',
// identifier: 'author_date_(format_respects_--date=_option)' },
// { code: '%aD',
// name: 'author date',
// fullDescription: 'author date, RFC2822 style',
// description: ', RFC2822 style',
// identifier: 'author_date_RFC2822_style' },
{ code: '%ar',
name: 'author date',
fullDescription: 'author date, relative',
description: ', relative',
identifier: 'author_date_relative' },
{ code: '%at',
name: 'author date',
fullDescription: 'author date, UNIX timestamp',
description: ', UNIX timestamp',
identifier: 'author_date_UNIX_timestamp' },
{ code: '%ai',
name: 'author date',
fullDescription: 'author date, ISO 8601-like format',
description: ', ISO 8601-like format',
identifier: 'author_date_ISO_8601-like_format' },
// { code: '%at',
// name: 'author date',
// fullDescription: 'author date, UNIX timestamp',
// description: ', UNIX timestamp',
// identifier: 'author_date_UNIX_timestamp' },
// { code: '%ai',
// name: 'author date',
// fullDescription: 'author date, ISO 8601-like format',
// description: ', ISO 8601-like format',
// identifier: 'author_date_ISO_8601-like_format' },
{ code: '%aI',
name: 'author date',
fullDescription: 'author date, strict ISO 8601 format',
description: ', strict ISO 8601 format',
identifier: 'author_date_strict_ISO_8601_format' },
identifier: 'author_date' },
{ code: '%cn',
name: 'committer name',
fullDescription: 'committer name',
Expand All @@ -88,7 +89,7 @@ exports.fields = [ { code: '%H',
name: 'committer name',
fullDescription: 'committer name (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'committer_name_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
identifier: 'committer_name_mailmap' },
{ code: '%ce',
name: 'committer email',
fullDescription: 'committer email',
Expand All @@ -98,47 +99,47 @@ exports.fields = [ { code: '%H',
name: 'committer email',
fullDescription: 'committer email (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'committer_email_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
{ code: '%cd',
name: 'committer date',
fullDescription: 'committer date (format respects --date= option)',
description: ' (format respects --date= option)',
identifier: 'committer_date_(format_respects_--date=_option)' },
{ code: '%cD',
name: 'committer date',
fullDescription: 'committer date, RFC2822 style',
description: ', RFC2822 style',
identifier: 'committer_date_RFC2822_style' },
identifier: 'committer_email_mailmap' },
// { code: '%cd',
// name: 'committer date',
// fullDescription: 'committer date (format respects --date= option)',
// description: ' (format respects --date= option)',
// identifier: 'committer_date_(format_respects_--date=_option)' },
// { code: '%cD',
// name: 'committer date',
// fullDescription: 'committer date, RFC2822 style',
// description: ', RFC2822 style',
// identifier: 'committer_date_RFC2822_style' },
{ code: '%cr',
name: 'committer date',
fullDescription: 'committer date, relative',
description: ', relative',
identifier: 'committer_date_relative' },
{ code: '%ct',
name: 'committer date',
fullDescription: 'committer date, UNIX timestamp',
description: ', UNIX timestamp',
identifier: 'committer_date_UNIX_timestamp' },
{ code: '%ci',
name: 'committer date',
fullDescription: 'committer date, ISO 8601-like format',
description: ', ISO 8601-like format',
identifier: 'committer_date_ISO_8601-like_format' },
// { code: '%ct',
// name: 'committer date',
// fullDescription: 'committer date, UNIX timestamp',
// description: ', UNIX timestamp',
// identifier: 'committer_date_UNIX_timestamp' },
// { code: '%ci',
// name: 'committer date',
// fullDescription: 'committer date, ISO 8601-like format',
// description: ', ISO 8601-like format',
// identifier: 'committer_date_ISO_8601-like_format' },
{ code: '%cI',
name: 'committer date',
fullDescription: 'committer date, strict ISO 8601 format',
description: ', strict ISO 8601 format',
identifier: 'committer_date_strict_ISO_8601_format' },
{ code: '%d',
name: 'ref names',
fullDescription: 'ref names, like the --decorate option of git-log[1]',
description: ', like the --decorate option of git-log[1]',
identifier: 'ref_names' },
identifier: 'committer_date' },
// { code: '%d',
// name: 'ref names',
// fullDescription: 'ref names, like the --decorate option of git-log[1]',
// description: ', like the --decorate option of git-log[1]',
// identifier: 'ref_names' },
{ code: '%D',
name: 'ref names without the "',
fullDescription: 'ref names without the " (", ")" wrapping.',
description: ' (", ")" wrapping.',
identifier: 'ref_names_without_the_"' },
identifier: 'ref_names' },
{ code: '%e',
name: 'encoding',
fullDescription: 'encoding',
Expand All @@ -153,7 +154,7 @@ exports.fields = [ { code: '%H',
name: 'sanitized subject line',
fullDescription: 'sanitized subject line, suitable for a filename',
description: ', suitable for a filename',
identifier: 'sanitized_subject_line' },
identifier: 'sanitized_subject' },
{ code: '%b',
name: 'body',
fullDescription: 'body',
Expand All @@ -173,22 +174,22 @@ exports.fields = [ { code: '%H',
name: 'raw verification message from GPG for a signed commit',
fullDescription: 'raw verification message from GPG for a signed commit',
description: '',
identifier: 'raw_verification_message_from_GPG_for_a_signed_commit' },
identifier: 'raw_GPG_verification_message' },
{ code: '%G?',
name: 'show "G" for a good',
fullDescription: 'show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature',
description: ' (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature',
identifier: 'show_"G"_for_a_good' },
identifier: 'signature_validity' },
{ code: '%GS',
name: 'show the name of the signer for a signed commit',
fullDescription: 'show the name of the signer for a signed commit',
description: '',
identifier: 'show_the_name_of_the_signer_for_a_signed_commit' },
identifier: 'signer_name' },
{ code: '%GK',
name: 'show the key used to sign a signed commit',
fullDescription: 'show the key used to sign a signed commit',
description: '',
identifier: 'show_the_key_used_to_sign_a_signed_commit' },
identifier: 'key' },
{ code: '%gD',
name: 'reflog selector',
fullDescription: 'reflog selector, e.g., refs/stash@{1} or refs/stash@{2 minutes ago}; the format follows the rules described for the -g option. The portion before the @ is the refname as given on the command line (so git log -g refs/heads/master would yield refs/heads/master@{0}).',
Expand All @@ -208,7 +209,7 @@ exports.fields = [ { code: '%H',
name: 'reflog identity name',
fullDescription: 'reflog identity name (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'reflog_identity_name_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
identifier: 'reflog_identity_name_mailmap' },
{ code: '%ge',
name: 'reflog identity email',
fullDescription: 'reflog identity email',
Expand All @@ -218,9 +219,13 @@ exports.fields = [ { code: '%H',
name: 'reflog identity email',
fullDescription: 'reflog identity email (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
description: ' (respecting .mailmap, see git-shortlog[1] or git-blame[1])',
identifier: 'reflog_identity_email_(respecting_.mailmap_see_git-shortlog[1]_or_git-blame[1])' },
identifier: 'reflog_identity_email_mailmap' },
{ code: '%gs',
name: 'reflog subject',
fullDescription: 'reflog subject',
description: '',
identifier: 'reflog_subject' } ];
identifier: 'reflog_subject' } ];

const formatString = exports.formatString = fields.map(field =>
`${ field.code }%x00`
).join('');
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,4 @@ const output = `
exports.fields = ${ inspect(fields) };
`;

fs.writeFileSync(path.join(__dirname, 'git-log-fields.js'), output);
fs.writeFileSync(path.join(__dirname, 'git-log-fields.es'), output);
6 changes: 3 additions & 3 deletions scripts/gitlogg-generate-log.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ runJs() {
shift
if [[ "$GITLOGG_DEV" = "" ]]; then
# Run precompiled .compiled.js
node "${script%.js}.compiled.js" "$@"
node "${script%.es}.js" "$@"
else
# Development: transpile .js at runtime
babel "$script" | node "$@"
fi
}

workerFile="$__dirname/output-intermediate-gitlog.sh"
workerFile="$__dirname/output-intermediate-gitlog.es"

# define path to 'json' parser
jsonParser="$__dirname/gitlogg-parse-json.js"
jsonParser="$__dirname/gitlogg-parse-json.es"

# Display system usage and exit
usage()
Expand Down
64 changes: 64 additions & 0 deletions scripts/gitlogg-parse-json.es
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
var fs = require('fs'),
path = require('path'),
chalk = require('chalk'),
{chunk} = require('lodash'),
{fields: gitLogFields} = require('./git-log-fields'),
// Read and write from file descriptors. Bash script will hook these up.
input_file = 3,
output_file = 4;

try {
require('source-map-support').install();
} catch(e) {}

console.log(chalk.yellow('Generating JSON output...'));

var changes = function(data, index) {
var v = data.split(',')[index] || 0;
var w = 0;
if (v !== 0) {
var w = v.split(' ')[1]; // the number of changes is second on the array
}
return parseInt(w);
};

console.time(chalk.green('JSON output generated in'));


const fields = [
{identifier: 'repository'},
...gitLogFields,
{identifier: 'shortstats'}
];

let input = fs.readFileSync(input_file, 'utf8').split('\0');
input.shift();
const totalFields = fields.length;
const inputCommits = chunk(input, totalFields);

const output = {};
inputCommits.forEach(item => {
// The last field for each commit includes the trailing newline output by `git log`; remove it
item[totalFields - 1] = item[totalFields - 1].slice(0, -1);

const commit = {};
fields.forEach((field, i) => {
commit[field.identifier] = item[i];
});
const stats = commit.shortstats;
commit.files_changed = changes(stats, 0);
const insertions = commit.insertions = changes(stats, 1);
const deletions = commit.deletions = changes(stats, 2);
commit.impact = insertions - deletions;
// TODO reimplement commit_nr

const repository = commit.repository;
output[repository] = output[repository] || [];
output[repository].push(commit);
});

console.timeEnd(chalk.green('JSON output generated in'));

console.log(chalk.yellow('Writing output to file...'));

fs.writeFileSync(output_file, JSON.stringify(output, null, 2));
Loading

0 comments on commit 3cfdf91

Please sign in to comment.