Skip to content

Instantly share code, notes, and snippets.

@mracette
Last active August 15, 2020 12:01
Show Gist options
  • Save mracette/2e3b8585872b2f8e146e1f9734cfc474 to your computer and use it in GitHub Desktop.
Save mracette/2e3b8585872b2f8e146e1f9734cfc474 to your computer and use it in GitHub Desktop.
Git hook tailored for js13k development. It runs build steps and logs the project size at each step.
/*
You will need to configure the global path variables to point to the directories
in your project, as well as to replace any execSync() commands with the build
commands that you are using.
To enable this hook, create .git/hooks/prepare-commit-msg (you may need to unhide
the .git/* folder), make it executable using chmod +x .git/hooks/prepare-commit-msg,
and add the following code in that file to point the hook to this source:
#!/usr/bin/env node
const pathToCustomHook = "../../hooks/prepare-commit-msg.js";
const runHook = require(pathToCustomHook);
runHook(process.argv);
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const ROOT_FOLDER = path.join(__dirname, '..');
const SOURCE_FOLDER = path.join(ROOT_FOLDER, 'src');
const BUILD_FOLDER = path.join(ROOT_FOLDER, 'build');
const COMPRESSED_BUILD_FOLDER = path.join(ROOT_FOLDER, 'build-min');
const COMPRESSED_BUILD_FILE = path.join(COMPRESSED_BUILD_FOLDER, 'build.zip');
const COMMIT_LOG_PATH = path.join(ROOT_FOLDER, 'commit-log.md');
function getFolderSize(path) {
const stout = execSync(`ls -l ${path} | awk '{sum+=$5} END {printf sum}'`, {
encoding: 'utf8'
});
const by = parseInt(stout);
const kb = (by / 1024).toFixed(2);
return [kb, by];
}
function checkExists(path) {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
}
function runHook(args) {
let LOG_MESSAGE = '';
// we will need these folders
checkExists(BUILD_FOLDER);
checkExists(COMPRESSED_BUILD_FOLDER);
// add the commit message
const commitMessage = args
? fs.readFileSync(args[2], { encoding: 'utf8' })
: 'no commit\n';
LOG_MESSAGE += `**${commitMessage.trim()}** - `;
// add the current date
LOG_MESSAGE += `*${new Date().toUTCString()}*\n`;
// add table header
LOG_MESSAGE += `| Measure | Size (kb) | Size (bytes) | Reduction |\n`;
LOG_MESSAGE += `| --- | --- | --- | --- |\n`;
// log the size of the uncompressed source
const [kb0, bytes0] = getFolderSize(path.join(SOURCE_FOLDER, '/*'));
LOG_MESSAGE += `| Raw Source Code | ${kb0} kb | ${bytes0} | NA |\n`;
// perform the production build and log new size
execSync(`rm -rf ${path.join(BUILD_FOLDER, '/*')}`);
execSync('rollup -c --environment BUILD:production');
const [kb1, bytes1] = getFolderSize(path.join(BUILD_FOLDER, '/*'));
LOG_MESSAGE += `| Build | ${kb1} kb | ${bytes1} | ${
bytes1 < bytes0 ? '-' : '+'
}${Math.round((100 * (bytes0 - bytes1)) / bytes0)}% |\n`;
// perform .zip compression and log new size
execSync(`rm -rf ${path.join(COMPRESSED_BUILD_FOLDER, '/*')}`);
execSync(`cd ${BUILD_FOLDER}; zip -r -j ${COMPRESSED_BUILD_FILE} ./*`);
const [kb2, bytes2] = getFolderSize(path.join(COMPRESSED_BUILD_FOLDER, '/*'));
LOG_MESSAGE += `| Compressed Build | ${kb2} kb | ${bytes2} | ${
bytes2 < bytes1 ? '-' : '+'
}${Math.round((100 * (bytes1 - bytes2)) / bytes1)}% |\n`;
// perform adv zip and log new size
execSync('advzip -z -4 -i 1000 ' + COMPRESSED_BUILD_FILE);
const [kb3, bytes3] = getFolderSize(path.join(COMPRESSED_BUILD_FOLDER, '/*'));
LOG_MESSAGE += `| Compressed Build (Adv Zip) | ${kb3} kb | ${bytes3} | ${
bytes3 < bytes2 ? '-' : '+'
}${Math.round((100 * (bytes2 - bytes3)) / bytes2)}% |\n`;
// breaks for the next entry:
LOG_MESSAGE += '\n\n';
// update the log
fs.open(COMMIT_LOG_PATH, 'a+', (err, fd) => {
fs.write(fd, LOG_MESSAGE, null, (err) => {
if (err) throw err;
});
});
}
module.exports = runHook;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment