diff --git a/index.js b/index.js index 9900001..1e8a314 100755 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ #!/usr/bin/env node const initializeGitRepo = require("./lib/initializeRepo"); +const initializeGitGlobal = require("./lib/globalRepos"); const emojifyCommit = require("./lib/emojifyCommit"); const getCommitMessage = require("./lib/getCommitMessage"); const writeMessage = require("./lib/writeMessage"); diff --git a/lib/getConfig.js b/lib/getConfig.js index 9ea01d3..7db81b1 100644 --- a/lib/getConfig.js +++ b/lib/getConfig.js @@ -1,5 +1,7 @@ const cosmiconfig = require("cosmiconfig"); const explorer = cosmiconfig("commoji"); +const path = require("path"); +const fs = require("fs"); module.exports = getConfig = () => { const result = explorer.searchSync(); @@ -8,5 +10,5 @@ module.exports = getConfig = () => { return result.config; } - return explorer.loadSync("./.defaultrc.json").config; + return explorer.loadSync(path.resolve(__dirname, "../.defaultrc.json")).config; }; diff --git a/lib/globalRepos.js b/lib/globalRepos.js new file mode 100644 index 0000000..edc680b --- /dev/null +++ b/lib/globalRepos.js @@ -0,0 +1,102 @@ +const fs = require("fs"); +const path = require("path"); +const readline = require('readline'); +const { exec } = require('child_process'); +const homedir = require('os').homedir(); + +// Takes the commit message and runs it through commoji +const commojiHook = `#!/bin/sh +prepareCommitMsgPath="$PWD/.git/hooks/prepare-commit-msg" +preCommitPath="$PWD/.git/hooks/pre-commit" + +if [ -f "$preCommitPath" ] +then + $preCommitPath +fi + +if [ -f "$prepareCommitMsgPath" ] +then + $prepareCommitMsgPath $1 +fi + +exec < /dev/tty +commoji $1 +`; +// Where the global hook will be located +const gitHooksPath = "/usr/local/share/git-core/templates/hooks"; +// Command to run to set up global hooks path (git 2.9) +const cmdConfigCoreHooksPath = "git config --global core.hooksPath"; +// Path where prepare-commit-msg will reside (has our commojiHook) +const prepareMessageHook = path.join(gitHooksPath, "prepare-commit-msg"); + +/** + */ + + module.exports = globalRepos = async () => { + let hookExists; + + try { + // Synchronously test the user's permissions for the file + // F_OK: Constant for fs.access(). File is visible to the calling process + fs.accessSync(gitHooksPath, fs.constants.F_OK); + hookExists = true; + } catch(_) { + hookExists = false; + } + + if (hookExists) { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.question(` +A prepare-commit-msg hook already exists at ${gitHooksPath}. +Would you like to overwite the existing hook? (y/N) +`, async (answer) => { + // Exit if user does not want to override their hook + if (!answer.match(/^(y|yes)$/gi)) { + rl.close(); + return; + } + + // Close readline + rl.close(); + + // Create folders where hook will reside if does not exist + await exec(`mkdir -p ${gitHooksPath}`, err => { + if (err) { + console.log(`Unable to make folders ${gitHooksPath}: ${err}`); + return; + } + }); + + // Create prepare-commit-msg file if does not exist + await exec(`touch ${prepareMessageHook}`, err => { + if (err) { + console.log(`Unable to create file ${prepareMessageHook}: ${err}`); + return; + } + }); + + await exec(`chmod +x ${prepareMessageHook}`, err => { + if (err) { + console.log(`Unable to add executionable permission to ${prepareMessageHook}`) + return; + } + }); + + // Write hook to folder (replace any existing) + fs.writeFileSync(prepareMessageHook, commojiHook, {mode: 0o777}); + + // Set up global config so commit will look at that hook by default (git 2.9) + await exec(`${cmdConfigCoreHooksPath} ${gitHooksPath}`, err => { + if (err) { + console.log(`Unable to set up global core.hooks_path '${cmdConfigCoreHooksPath} ${gitHooksPath}': ${err}`); + return; + } + console.log("✨ Successfully installed commoji globally 🌏 ! You can now commit as you normally would.") + }); + }); + } + } diff --git a/lib/initializeRepo.js b/lib/initializeRepo.js index 6f76987..7099ccc 100644 --- a/lib/initializeRepo.js +++ b/lib/initializeRepo.js @@ -1,6 +1,7 @@ const fs = require("fs"); const path = require("path"); +// Runs it with the location of the commit message const commojiHook = `#!/bin/sh exec < /dev/tty commoji $1