Search code examples
node.jshusky

Husky pre-commit hook finishes after commit


The following script was written in order to sort JSON files by key on pre-commit hook:

 /*
 * Will reorder all files in given path.
 */

const sortJson = require("sort-json");
const fs = require("fs");
const chalk = require("chalk");

const log = console.log;
const translationsPath = process.argv.slice(2).join(" ");

function readFiles(dirname) {
  try {
    return fs.readdirSync(dirname);
  } catch (e) {
    log(chalk.red(`Failed reading files from path; ${e}`));
  }
}

log(
  chalk.bgGreen(
    `Running json sort pre-commit hook on path: ${translationsPath}`
  )
);

const files = readFiles(translationsPath);
files.forEach((file) => {
  log(chalk.yellow(`Sorting ${file}...`));
  try {
    sortJson.overwrite(`${translationsPath}\\${file}`);
    log(chalk.green(`Finished sorting ${file}`));
  } catch (e) {
    log(chalk.red(`Failed sorting file ${file}; ${e}`));
  }
});

log(
  chalk.bgGreen(
    `Finished sorting files`
  )
);

I'm attaching the script to my package.json with husky precommit hook:

  "scripts": {
    "sort-translations": "node ./scripts/husky/json-sort src/assets/translations",
    ...
  },
  "husky": {
    "hooks": {
      "pre-commit": "npm run sort-translations"
    }
  },

The result is that the commit is finished, and only then the script finishes with the created unstage changes. The script itself runs synchronously with the Finished sorting files message printed last.

My question is, how can I make it synchronous; first finish running node ./scripts/husky/json-sort src/assets/translations, then git commit.

Thanks!


Solution

  • Thanks to @adelriosantiago comment, I figured it out.

    1. First of all, I started using readdirSync() instead of readdir(). Then I was able to verify (through logging) that the script indeed ends only when the files are edited. Unfortunately that wasn't enough - the hook still ended with uncommitted files.
    2. At this point I realized - it's not about the hook, it's about the git staging! The script ends it time, but the modified changes remain unstaged so they're not commited. So I've added && git add src/assets/translations to pre-commit hook.

    Now everything works as desired.